diff --git a/go.mod b/go.mod
index f4c233ea8..83a973b10 100644
--- a/go.mod
+++ b/go.mod
@@ -2,9 +2,11 @@ module github.com/sipeed/picoclaw
go 1.25.7
+replace charm.land/fantasy v0.8.1 => ./internal/fantasy
+
require (
+ charm.land/fantasy v0.8.1
github.com/adhocore/gronx v1.19.6
- github.com/anthropics/anthropic-sdk-go v1.22.1
github.com/bwmarrin/discordgo v0.29.0
github.com/caarlos0/env/v11 v11.3.1
github.com/chzyer/readline v1.5.1
@@ -13,23 +15,41 @@ require (
github.com/larksuite/oapi-sdk-go/v3 v3.5.3
github.com/mymmrac/telego v1.6.0
github.com/open-dingtalk/dingtalk-stream-sdk-go v0.9.1
- github.com/openai/openai-go/v3 v3.21.0
+ github.com/openai/openai-go/v2 v2.7.1
github.com/slack-go/slack v0.17.3
+ github.com/stretchr/testify v1.11.1
github.com/tencent-connect/botgo v0.2.1
+ github.com/tmc/langchaingo v0.1.14
+ github.com/tursodatabase/go-libsql v0.0.0-20251219133454-43644db490ff
golang.org/x/oauth2 v0.35.0
)
require (
github.com/andybalholm/brotli v1.2.0 // indirect
+ github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/bytedance/gopkg v0.1.3 // indirect
github.com/bytedance/sonic v1.15.0 // indirect
github.com/bytedance/sonic/loader v0.5.0 // indirect
+ github.com/charmbracelet/x/exp/slice v0.0.0-20250904123553-b4e2667e5ad5 // indirect
+ github.com/charmbracelet/x/json v0.2.0 // indirect
github.com/cloudwego/base64x v0.1.6 // indirect
+ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
+ github.com/dlclark/regexp2 v1.10.0 // indirect
+ github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e // indirect
github.com/go-resty/resty/v2 v2.17.1 // indirect
+ github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
+ github.com/goccy/go-yaml v1.19.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/grbit/go-json v0.11.0 // indirect
+ github.com/kaptinlin/go-i18n v0.2.3 // indirect
+ github.com/kaptinlin/jsonpointer v0.4.9 // indirect
+ github.com/kaptinlin/jsonschema v0.6.10 // indirect
+ github.com/kaptinlin/messageformat-go v0.4.9 // indirect
github.com/klauspost/compress v1.18.4 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
+ github.com/libsql/sqlite-antlr4-parser v0.0.0-20240327125255-dbf53b6cbf06 // indirect
+ github.com/pkoukk/tiktoken-go v0.1.6 // indirect
+ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/tidwall/gjson v1.18.0 // indirect
github.com/tidwall/match v1.2.0 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
@@ -38,9 +58,17 @@ require (
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.69.0 // indirect
github.com/valyala/fastjson v1.6.7 // indirect
+ gitlab.com/golang-commonmark/html v0.0.0-20191124015941-a22733972181 // indirect
+ gitlab.com/golang-commonmark/linkify v0.0.0-20191026162114-a0c2df6c8f82 // indirect
+ gitlab.com/golang-commonmark/markdown v0.0.0-20211110145824-bf3e522c626a // indirect
+ gitlab.com/golang-commonmark/mdurl v0.0.0-20191124015652-932350d1cb84 // indirect
+ gitlab.com/golang-commonmark/puny v0.0.0-20191124015043-9f83538fa04f // indirect
golang.org/x/arch v0.24.0 // indirect
golang.org/x/crypto v0.48.0 // indirect
+ golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect
golang.org/x/net v0.50.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.41.0 // indirect
+ golang.org/x/text v0.34.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/go.sum b/go.sum
index 9174d2889..b1d48dbae 100644
--- a/go.sum
+++ b/go.sum
@@ -3,8 +3,8 @@ github.com/adhocore/gronx v1.19.6 h1:5KNVcoR9ACgL9HhEqCm5QXsab/gI4QDIybTAWcXDKDc
github.com/adhocore/gronx v1.19.6/go.mod h1:7oUY1WAU8rEJWmAxXR2DN0JaO4gi9khSgKjiRypqteg=
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
-github.com/anthropics/anthropic-sdk-go v1.22.1 h1:xbsc3vJKCX/ELDZSpTNfz9wCgrFsamwFewPb1iI0Xh0=
-github.com/anthropics/anthropic-sdk-go v1.22.1/go.mod h1:WTz31rIUHUHqai2UslPpw5CwXrQP3geYBioRV4WOLvE=
+github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
+github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
github.com/bwmarrin/discordgo v0.29.0 h1:FmWeXFaKUwrcL3Cx65c20bTRW+vOb6k8AnaP+EgjDno=
github.com/bwmarrin/discordgo v0.29.0/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY=
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
@@ -17,6 +17,10 @@ github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5m
github.com/caarlos0/env/v11 v11.3.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/charmbracelet/x/exp/slice v0.0.0-20250904123553-b4e2667e5ad5 h1:DTSZxdV9qQagD4iGcAt9RgaRBZtJl01bfKgdLzUzUPI=
+github.com/charmbracelet/x/exp/slice v0.0.0-20250904123553-b4e2667e5ad5/go.mod h1:vI5nDVMWi6veaYH+0Fmvpbe/+cv/iJfMntdh+N0+Tms=
+github.com/charmbracelet/x/json v0.2.0 h1:DqB+ZGx2h+Z+1s98HOuOyli+i97wsFQIxP2ZQANTPrQ=
+github.com/charmbracelet/x/json v0.2.0/go.mod h1:opFIflx2YgXgi49xVUu8gEQ21teFAxyMwvOiZhIvWNM=
github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM=
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
@@ -27,11 +31,16 @@ github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
+github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
+github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
+github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e h1:Lf/gRkoycfOBPa42vU2bbgPurFong6zXeFtPoxholzU=
+github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e/go.mod h1:uNVvRXArCGbZ508SxYYTC5v1JWoz2voff5pm25jU1Ok=
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q=
github.com/go-resty/resty/v2 v2.17.1 h1:x3aMpHK1YM9e4va/TMDRlusDDoZiQ+ViDu/WpA6xTM4=
@@ -39,6 +48,10 @@ github.com/go-resty/resty/v2 v2.17.1/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2m
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
+github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
+github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
+github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
+github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -56,6 +69,8 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -66,6 +81,14 @@ github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
github.com/grbit/go-json v0.11.0 h1:bAbyMdYrYl/OjYsSqLH99N2DyQ291mHy726Mx+sYrnc=
github.com/grbit/go-json v0.11.0/go.mod h1:IYpHsdybQ386+6g3VE6AXQ3uTGa5mquBme5/ZWmtzek=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/kaptinlin/go-i18n v0.2.3 h1:jyN/YOXXLcnGRBLdU+a8+6782B97fWE5aQqAHtvvk8Q=
+github.com/kaptinlin/go-i18n v0.2.3/go.mod h1:O+Ax4HkMO0Jt4OaP4E4WCx0PAADeWkwk8Jgt9bjAU1w=
+github.com/kaptinlin/jsonpointer v0.4.9 h1:o//bYf4PCvnMJIIX8bIg77KB6DO3wBPAabRyPRKh680=
+github.com/kaptinlin/jsonpointer v0.4.9/go.mod h1:9y0LgXavlmVE5FSHShY5LRlURJJVhbyVJSRWkilrTqA=
+github.com/kaptinlin/jsonschema v0.6.10 h1:CYded7nrwVu7pU1GaIjtd9dSzgqZjh7+LTKFaWqS08I=
+github.com/kaptinlin/jsonschema v0.6.10/go.mod h1:ZXZ4K5KrRmCCF1i6dgvBsQifl+WTb8XShKj0NpQNrz8=
+github.com/kaptinlin/messageformat-go v0.4.9 h1:FR5j5n4aL4nG0afKn9vvANrKxLu7HjmbhJnw5ogIwAQ=
+github.com/kaptinlin/messageformat-go v0.4.9/go.mod h1:qZzrGrlvWDz2KyyvN3dOWcK9PVSRV1BnfnNU+zB/RWc=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=
@@ -75,11 +98,16 @@ github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/larksuite/oapi-sdk-go/v3 v3.5.3 h1:xvf8Dv29kBXC5/DNDCLhHkAFW8l/0LlQJimO5Zn+JUk=
github.com/larksuite/oapi-sdk-go/v3 v3.5.3/go.mod h1:ZEplY+kwuIrj/nqw5uSCINNATcH3KdxSN7y+UxYY5fI=
+github.com/libsql/sqlite-antlr4-parser v0.0.0-20240327125255-dbf53b6cbf06 h1:JLvn7D+wXjH9g4Jsjo+VqmzTUpl/LX7vfr6VOfSWTdM=
+github.com/libsql/sqlite-antlr4-parser v0.0.0-20240327125255-dbf53b6cbf06/go.mod h1:FUkZ5OHjlGPjnM2UyGJz9TypXQFgYqw6AFNO1UiROTM=
github.com/mymmrac/telego v1.6.0 h1:Zc8rgyHozvd/7ZgyrigyHdAF9koHYMfilYfyB6wlFC0=
github.com/mymmrac/telego v1.6.0/go.mod h1:xt6ZWA8zi8KmuzryE1ImEdl9JSwjHNpM4yhC7D8hU4Y=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
@@ -92,13 +120,24 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/open-dingtalk/dingtalk-stream-sdk-go v0.9.1 h1:Lb/Uzkiw2Ugt2Xf03J5wmv81PdkYOiWbI8CNBi1boC8=
github.com/open-dingtalk/dingtalk-stream-sdk-go v0.9.1/go.mod h1:ln3IqPYYocZbYvl9TAOrG/cxGR9xcn4pnZRLdCTEGEU=
-github.com/openai/openai-go/v3 v3.21.0 h1:3GpIR/W4q/v1uUOVuK3zYtQiF3DnRrZag/sxbtvEdtc=
-github.com/openai/openai-go/v3 v3.21.0/go.mod h1:cdufnVK14cWcT9qA1rRtrXx4FTRsgbDPW7Ia7SS5cZo=
+github.com/openai/openai-go/v2 v2.7.1 h1:/tfvTJhfv7hTSL8mWwc5VL4WLLSDL5yn9VqVykdu9r8=
+github.com/openai/openai-go/v2 v2.7.1/go.mod h1:jrJs23apqJKKbT+pqtFgNKpRju/KP9zpUTZhz3GElQE=
+github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
+github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkoukk/tiktoken-go v0.1.6 h1:JF0TlJzhTbrI30wCvFuiw6FzP2+/bR+FIxUdgEAcUsw=
+github.com/pkoukk/tiktoken-go v0.1.6/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
+github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
+github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/slack-go/slack v0.17.3 h1:zV5qO3Q+WJAQ/XwbGfNFrRMaJ5T/naqaonyPV/1TP4g=
github.com/slack-go/slack v0.17.3/go.mod h1:X+UqOufi3LYQHDnMG1vxf0J8asC6+WllXrVrhl8/Prk=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -127,6 +166,10 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
+github.com/tmc/langchaingo v0.1.14 h1:o1qWBPigAIuFvrG6cjTFo0cZPFEZ47ZqpOYMjM15yZc=
+github.com/tmc/langchaingo v0.1.14/go.mod h1:aKKYXYoqhIDEv7WKdpnnCLRaqXic69cX9MnDUk72378=
+github.com/tursodatabase/go-libsql v0.0.0-20251219133454-43644db490ff h1:Hvxz9W8fWpSg9xkiq8/q+3cVJo+MmLMfkjdS/u4nWFY=
+github.com/tursodatabase/go-libsql v0.0.0-20251219133454-43644db490ff/go.mod h1:TjsB2miB8RW2Sse8sdxzVTdeGlx74GloD5zJYUC38d8=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
@@ -140,6 +183,18 @@ github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3i
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+gitlab.com/golang-commonmark/html v0.0.0-20191124015941-a22733972181 h1:K+bMSIx9A7mLES1rtG+qKduLIXq40DAzYHtb0XuCukA=
+gitlab.com/golang-commonmark/html v0.0.0-20191124015941-a22733972181/go.mod h1:dzYhVIwWCtzPAa4QP98wfB9+mzt33MSmM8wsKiMi2ow=
+gitlab.com/golang-commonmark/linkify v0.0.0-20191026162114-a0c2df6c8f82 h1:oYrL81N608MLZhma3ruL8qTM4xcpYECGut8KSxRY59g=
+gitlab.com/golang-commonmark/linkify v0.0.0-20191026162114-a0c2df6c8f82/go.mod h1:Gn+LZmCrhPECMD3SOKlE+BOHwhOYD9j7WT9NUtkCrC8=
+gitlab.com/golang-commonmark/markdown v0.0.0-20211110145824-bf3e522c626a h1:O85GKETcmnCNAfv4Aym9tepU8OE0NmcZNqPlXcsBKBs=
+gitlab.com/golang-commonmark/markdown v0.0.0-20211110145824-bf3e522c626a/go.mod h1:LaSIs30YPGs1H5jwGgPhLzc8vkNc/k0rDX/fEZqiU/M=
+gitlab.com/golang-commonmark/mdurl v0.0.0-20191124015652-932350d1cb84 h1:qqjvoVXdWIcZCLPMlzgA7P9FZWdPGPvP/l3ef8GzV6o=
+gitlab.com/golang-commonmark/mdurl v0.0.0-20191124015652-932350d1cb84/go.mod h1:IJZ+fdMvbW2qW6htJx7sLJ04FEs4Ldl/MDsJtMKywfw=
+gitlab.com/golang-commonmark/puny v0.0.0-20191124015043-9f83538fa04f h1:Wku8eEdeJqIOFHtrfkYUByc4bCaTeA6fL0UJgfEiFMI=
+gitlab.com/golang-commonmark/puny v0.0.0-20191124015043-9f83538fa04f/go.mod h1:Tiuhl+njh/JIg0uS/sOJVYi0x2HEa5rc1OAaVsb5tAs=
+gitlab.com/opennota/wd v0.0.0-20180912061657-c5d65f63c638 h1:uPZaMiz6Sz0PZs3IZJWpU5qHKGNy///1pacZC9txiUI=
+gitlab.com/opennota/wd v0.0.0-20180912061657-c5d65f63c638/go.mod h1:EGRJaqe2eO9XGmFtQCvV3Lm9NLico3UhFwUpCG/+mVU=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
golang.org/x/arch v0.24.0 h1:qlJ3M9upxvFfwRM51tTg3Yl+8CP9vCC1E7vlFpgv99Y=
@@ -152,6 +207,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
+golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY=
+golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@@ -209,14 +266,17 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
-golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
+golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
+golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
+golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
+golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -238,6 +298,7 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
@@ -245,7 +306,12 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
+gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
+sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
+sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
diff --git a/internal/fantasy/CRUSH.md b/internal/fantasy/CRUSH.md
new file mode 100644
index 000000000..ad5079839
--- /dev/null
+++ b/internal/fantasy/CRUSH.md
@@ -0,0 +1,29 @@
+# CRUSH.md - Fantasy AI SDK
+
+## Build/Test/Lint Commands
+- **Build**: `go build ./...`
+- **Test all**: `task test` or `go test ./... -count=1`
+- **Test single**: `go test -run TestName ./package -v`
+- **Test with args**: `task test -- -v -run TestName`
+- **Lint**: `task lint` or `golangci-lint run`
+- **Format**: `task fmt` or `gofmt -s -w .`
+- **Modernize**: `task modernize` or `modernize -fix ./...`
+
+## Code Style Guidelines
+- **Package naming**: lowercase, single word (ai, openai, anthropic, google)
+- **Imports**: standard library first, then third-party, then local packages
+- **Error handling**: Use custom error types with structured fields, wrap with context
+- **Types**: Use type aliases for function signatures (`type Option = func(*options)`)
+- **Naming**: CamelCase for exported, camelCase for unexported
+- **Constants**: Use const blocks with descriptive names (ProviderName, DefaultURL)
+- **Structs**: Embed anonymous structs for composition (APICallError embeds *AIError)
+- **Functions**: Return error as last parameter, use context.Context as first param
+- **Testing**: Use testify/assert, table-driven tests, recorder pattern for HTTP mocking
+- **Comments**: Godoc format for exported functions, explain complex logic inline
+- **JSON**: Use struct tags for marshaling, handle empty values gracefully
+
+## Project Structure
+- `/ai` - Core AI abstractions and agent logic
+- `/openai`, `/anthropic`, `/google` - Provider implementations
+- `/providertests` - Cross-provider integration tests with VCR recordings
+- `/examples` - Usage examples for different patterns
\ No newline at end of file
diff --git a/internal/fantasy/LICENSE b/internal/fantasy/LICENSE
new file mode 100644
index 000000000..f433b1a53
--- /dev/null
+++ b/internal/fantasy/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/internal/fantasy/NOTICE b/internal/fantasy/NOTICE
new file mode 100644
index 000000000..d27814211
--- /dev/null
+++ b/internal/fantasy/NOTICE
@@ -0,0 +1,13 @@
+Copyright 2025-2026 Charmbracelet, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/internal/fantasy/README.md b/internal/fantasy/README.md
new file mode 100644
index 000000000..e37aa8a21
--- /dev/null
+++ b/internal/fantasy/README.md
@@ -0,0 +1,98 @@
+# Fantasy
+
+
+ 
+
+
+
+
+
+Build AI agents with Go. Multi-provider, multi-model, one API.
+
+1. Choose a model and provider
+2. Add some tools
+3. Compile to native machine code and let it rip
+
+> [!NOTE]
+> Fantasy is currently a preview. Expect API changes.
+
+```go
+import "charm.land/fantasy"
+import "charm.land/fantasy/providers/openrouter"
+
+// Choose your fave provider.
+provider, err := openrouter.New(openrouter.WithAPIKey(myHotKey))
+if err != nil {
+ fmt.Fprintln(os.Stderr, "Whoops:", err)
+ os.Exit(1)
+}
+
+ctx := context.Background()
+
+// Pick your fave model.
+model, err := provider.LanguageModel(ctx, "moonshotai/kimi-k2")
+if err != nil {
+ fmt.Fprintln(os.Stderr, "Dang:", err)
+ os.Exit(1)
+}
+
+// Make your own tools.
+cuteDogTool := fantasy.NewAgentTool(
+ "cute_dog_tool",
+ "Provide up-to-date info on cute dogs.",
+ fetchCuteDogInfoFunc,
+)
+
+// Equip your agent.
+agent := fantasy.NewAgent(
+ model,
+ fantasy.WithSystemPrompt("You are a moderately helpful, dog-centric assistant."),
+ fantasy.WithTools(cuteDogTool),
+)
+
+// Put that agent to work!
+const prompt = "Find all the cute dogs in Silver Lake, Los Angeles."
+result, err := agent.Generate(ctx, fantasy.AgentCall{Prompt: prompt})
+if err != nil {
+ fmt.Fprintln(os.Stderr, "Oof:", err)
+ os.Exit(1)
+}
+fmt.Println(result.Response.Content.Text())
+```
+
+š For the full implementation and more [see the examples directory](https://github.com/charmbracelet/fantasy/tree/main/examples).
+
+## Multi-model? Multi-provider?
+
+Yeah! Fantasy is designed to support a wide variety of providers and models under a single API. While many providers such as Microsoft Azure, Amazon Bedrock, and OpenRouter have dedicated packages in Fantasy, many others work just fine with `openaicompat`, the generic OpenAI-compatible layer. That said, if you find a provider thatās not compatible and needs special treatment, please let us know in an issue (or open a PR).
+
+## Work in Progress
+
+We built Fantasy to power [Crush](https://github.com/charmbracelet/crush), a hot coding agent for glamourously invincible development. Given that, Fantasy does not yet support things like:
+
+- Image models
+- Audio models
+- PDF uploads
+- Provider tools (e.g. web_search)
+
+For things youād like to see supported, PRs are welcome.
+
+## Whatcha think?
+
+Weād love to hear your thoughts on this project. Need help? We gotchu. You can find us on:
+
+- [Slack](https://charm.land/slack)
+- [Discord][discord]
+- [Twitter](https://twitter.com/charmcli)
+- [The Fediverse](https://mastodon.social/@charmcli)
+- [Bluesky](https://bsky.app/profile/charm.land)
+
+[discord]: https://charm.land/discord
+
+---
+
+Part of [Charm](https://charm.land).
+
+
+
+Charmēē±å¼ęŗ ⢠Charm loves open source
diff --git a/internal/fantasy/Taskfile.yaml b/internal/fantasy/Taskfile.yaml
new file mode 100644
index 000000000..34455b902
--- /dev/null
+++ b/internal/fantasy/Taskfile.yaml
@@ -0,0 +1,43 @@
+version: "3"
+
+tasks:
+ fmt:
+ desc: Run gofumpt for all packages
+ cmds:
+ - gofumpt -w .
+
+ modernize:
+ desc: Run modernize for all packages
+ cmds:
+ - modernize -fix ./...
+
+ lint:
+ desc: Run base linters for all packages
+ cmds:
+ - golangci-lint run
+
+ lint:fix:
+ desc: Run base linters for all packages and applies fixes if possible
+ cmds:
+ - golangci-lint run --fix
+
+ test:
+ desc: Run tests for all packages
+ cmds:
+ - go test ./... -count=1 {{.CLI_ARGS}}
+ release:
+ desc: Create and push a new tag following semver
+ vars:
+ NEXT:
+ sh: svu next --always || go run github.com/caarlos0/svu/v3@latest next --always
+ prompt: "This will release {{.NEXT}}. Continue?"
+ preconditions:
+ - sh: '[ $(git symbolic-ref --short HEAD) = "main" ]'
+ msg: Not on main branch
+ - sh: "[ $(git status --porcelain=2 | wc -l) = 0 ]"
+ msg: "Git is dirty"
+ cmds:
+ - git commit --allow-empty -m "{{.NEXT}}"
+ - git tag --annotate --sign -m "{{.NEXT}}" {{.NEXT}} {{.CLI_ARGS}}
+ - echo "Pushing {{.NEXT}}..."
+ - git push origin main --follow-tags
diff --git a/internal/fantasy/VENDORING.md b/internal/fantasy/VENDORING.md
new file mode 100644
index 000000000..bca6405a9
--- /dev/null
+++ b/internal/fantasy/VENDORING.md
@@ -0,0 +1,42 @@
+# Vendored: charm.land/fantasy v0.8.1
+
+## What This Is
+
+This directory contains a vendored copy of `charm.land/fantasy` v0.8.1, the Charmbracelet
+Fantasy LLM agent framework. We vendor it to enable direct modifications for PicoClaw-specific
+features (progressive disclosure, custom streaming hooks, tool call repair, etc.).
+
+## How It Works
+
+PicoClaw's `go.mod` contains a `replace` directive:
+
+```
+replace charm.land/fantasy v0.8.1 => ./internal/fantasy
+```
+
+This redirects all `charm.land/fantasy` imports to this local copy. No import paths
+need to change in either PicoClaw code or the fantasy source itself.
+
+## Syncing Upstream Updates
+
+To pull in a new upstream version:
+
+1. Check the upstream version: `go list -m -versions charm.land/fantasy`
+2. Download it: `go mod download charm.land/fantasy@vX.Y.Z`
+3. Copy to vendor: `cp -r $(go env GOMODCACHE)/charm.land/fantasy@vX.Y.Z/* internal/fantasy/`
+4. Fix permissions: `chmod -R u+w internal/fantasy/`
+5. Re-apply local patches (see below)
+6. Update the replace directive version in `go.mod` if needed
+7. Run `go mod tidy && go test ./...`
+
+## Local Patches
+
+Document all local modifications here:
+
+| Date | File | Description |
+|------|------|-------------|
+| (none yet) | ā | Initial vendor, no patches applied |
+
+## Original License
+
+Fantasy is licensed under the MIT License. See `LICENSE` in this directory.
diff --git a/internal/fantasy/agent.go b/internal/fantasy/agent.go
new file mode 100644
index 000000000..426beff16
--- /dev/null
+++ b/internal/fantasy/agent.go
@@ -0,0 +1,1426 @@
+package fantasy
+
+import (
+ "cmp"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "maps"
+ "slices"
+ "sync"
+
+ "charm.land/fantasy/schema"
+)
+
+// StepResult represents the result of a single step in an agent execution.
+type StepResult struct {
+ Response
+ Messages []Message
+}
+
+// stepExecutionResult encapsulates the result of executing a step with stream processing.
+type stepExecutionResult struct {
+ StepResult StepResult
+ ShouldContinue bool
+}
+
+// StopCondition defines a function that determines when an agent should stop executing.
+type StopCondition = func(steps []StepResult) bool
+
+// StepCountIs returns a stop condition that stops after the specified number of steps.
+func StepCountIs(stepCount int) StopCondition {
+ return func(steps []StepResult) bool {
+ return len(steps) >= stepCount
+ }
+}
+
+// HasToolCall returns a stop condition that stops when the specified tool is called in the last step.
+func HasToolCall(toolName string) StopCondition {
+ return func(steps []StepResult) bool {
+ if len(steps) == 0 {
+ return false
+ }
+ lastStep := steps[len(steps)-1]
+ toolCalls := lastStep.Content.ToolCalls()
+ for _, toolCall := range toolCalls {
+ if toolCall.ToolName == toolName {
+ return true
+ }
+ }
+ return false
+ }
+}
+
+// HasContent returns a stop condition that stops when the specified content type appears in the last step.
+func HasContent(contentType ContentType) StopCondition {
+ return func(steps []StepResult) bool {
+ if len(steps) == 0 {
+ return false
+ }
+ lastStep := steps[len(steps)-1]
+ for _, content := range lastStep.Content {
+ if content.GetType() == contentType {
+ return true
+ }
+ }
+ return false
+ }
+}
+
+// FinishReasonIs returns a stop condition that stops when the specified finish reason occurs.
+func FinishReasonIs(reason FinishReason) StopCondition {
+ return func(steps []StepResult) bool {
+ if len(steps) == 0 {
+ return false
+ }
+ lastStep := steps[len(steps)-1]
+ return lastStep.FinishReason == reason
+ }
+}
+
+// MaxTokensUsed returns a stop condition that stops when total token usage exceeds the specified limit.
+func MaxTokensUsed(maxTokens int64) StopCondition {
+ return func(steps []StepResult) bool {
+ var totalTokens int64
+ for _, step := range steps {
+ totalTokens += step.Usage.TotalTokens
+ }
+ return totalTokens >= maxTokens
+ }
+}
+
+// PrepareStepFunctionOptions contains the options for preparing a step in an agent execution.
+type PrepareStepFunctionOptions struct {
+ Steps []StepResult
+ StepNumber int
+ Model LanguageModel
+ Messages []Message
+}
+
+// PrepareStepResult contains the result of preparing a step in an agent execution.
+type PrepareStepResult struct {
+ Model LanguageModel
+ Messages []Message
+ System *string
+ ToolChoice *ToolChoice
+ ActiveTools []string
+ DisableAllTools bool
+ Tools []AgentTool
+}
+
+// ToolCallRepairOptions contains the options for repairing a tool call.
+type ToolCallRepairOptions struct {
+ OriginalToolCall ToolCallContent
+ ValidationError error
+ AvailableTools []AgentTool
+ SystemPrompt string
+ Messages []Message
+}
+
+type (
+ // PrepareStepFunction defines a function that prepares a step in an agent execution.
+ PrepareStepFunction = func(ctx context.Context, options PrepareStepFunctionOptions) (context.Context, PrepareStepResult, error)
+
+ // OnStepFinishedFunction defines a function that is called when a step finishes.
+ OnStepFinishedFunction = func(step StepResult)
+
+ // RepairToolCallFunction defines a function that repairs a tool call.
+ RepairToolCallFunction = func(ctx context.Context, options ToolCallRepairOptions) (*ToolCallContent, error)
+)
+
+type agentSettings struct {
+ systemPrompt string
+ maxOutputTokens *int64
+ temperature *float64
+ topP *float64
+ topK *int64
+ presencePenalty *float64
+ frequencyPenalty *float64
+ headers map[string]string
+ providerOptions ProviderOptions
+
+ // TODO: add support for provider tools
+ tools []AgentTool
+ maxRetries *int
+
+ model LanguageModel
+
+ stopWhen []StopCondition
+ prepareStep PrepareStepFunction
+ repairToolCall RepairToolCallFunction
+ onRetry OnRetryCallback
+}
+
+// AgentCall represents a call to an agent.
+type AgentCall struct {
+ Prompt string `json:"prompt"`
+ Files []FilePart `json:"files"`
+ Messages []Message `json:"messages"`
+ MaxOutputTokens *int64
+ Temperature *float64 `json:"temperature"`
+ TopP *float64 `json:"top_p"`
+ TopK *int64 `json:"top_k"`
+ PresencePenalty *float64 `json:"presence_penalty"`
+ FrequencyPenalty *float64 `json:"frequency_penalty"`
+ ActiveTools []string `json:"active_tools"`
+ ProviderOptions ProviderOptions
+ OnRetry OnRetryCallback
+ MaxRetries *int
+
+ StopWhen []StopCondition
+ PrepareStep PrepareStepFunction
+ RepairToolCall RepairToolCallFunction
+}
+
+// Agent-level callbacks.
+type (
+ // OnAgentStartFunc is called when agent starts.
+ OnAgentStartFunc func()
+
+ // OnAgentFinishFunc is called when agent finishes.
+ OnAgentFinishFunc func(result *AgentResult) error
+
+ // OnStepStartFunc is called when a step starts.
+ OnStepStartFunc func(stepNumber int) error
+
+ // OnStepFinishFunc is called when a step finishes.
+ OnStepFinishFunc func(stepResult StepResult) error
+
+ // OnFinishFunc is called when entire agent completes.
+ OnFinishFunc func(result *AgentResult)
+
+ // OnErrorFunc is called when an error occurs.
+ OnErrorFunc func(error)
+)
+
+// Stream part callbacks - called for each corresponding stream part type.
+type (
+ // OnChunkFunc is called for each stream part (catch-all).
+ OnChunkFunc func(StreamPart) error
+
+ // OnWarningsFunc is called for warnings.
+ OnWarningsFunc func(warnings []CallWarning) error
+
+ // OnTextStartFunc is called when text starts.
+ OnTextStartFunc func(id string) error
+
+ // OnTextDeltaFunc is called for text deltas.
+ OnTextDeltaFunc func(id, text string) error
+
+ // OnTextEndFunc is called when text ends.
+ OnTextEndFunc func(id string) error
+
+ // OnReasoningStartFunc is called when reasoning starts.
+ OnReasoningStartFunc func(id string, reasoning ReasoningContent) error
+
+ // OnReasoningDeltaFunc is called for reasoning deltas.
+ OnReasoningDeltaFunc func(id, text string) error
+
+ // OnReasoningEndFunc is called when reasoning ends.
+ OnReasoningEndFunc func(id string, reasoning ReasoningContent) error
+
+ // OnToolInputStartFunc is called when tool input starts.
+ OnToolInputStartFunc func(id, toolName string) error
+
+ // OnToolInputDeltaFunc is called for tool input deltas.
+ OnToolInputDeltaFunc func(id, delta string) error
+
+ // OnToolInputEndFunc is called when tool input ends.
+ OnToolInputEndFunc func(id string) error
+
+ // OnToolCallFunc is called when tool call is complete.
+ OnToolCallFunc func(toolCall ToolCallContent) error
+
+ // OnToolResultFunc is called when tool execution completes.
+ OnToolResultFunc func(result ToolResultContent) error
+
+ // OnSourceFunc is called for source references.
+ OnSourceFunc func(source SourceContent) error
+
+ // OnStreamFinishFunc is called when stream finishes.
+ OnStreamFinishFunc func(usage Usage, finishReason FinishReason, providerMetadata ProviderMetadata) error
+)
+
+// AgentStreamCall represents a streaming call to an agent.
+type AgentStreamCall struct {
+ Prompt string `json:"prompt"`
+ Files []FilePart `json:"files"`
+ Messages []Message `json:"messages"`
+ MaxOutputTokens *int64
+ Temperature *float64 `json:"temperature"`
+ TopP *float64 `json:"top_p"`
+ TopK *int64 `json:"top_k"`
+ PresencePenalty *float64 `json:"presence_penalty"`
+ FrequencyPenalty *float64 `json:"frequency_penalty"`
+ ActiveTools []string `json:"active_tools"`
+ Headers map[string]string
+ ProviderOptions ProviderOptions
+ OnRetry OnRetryCallback
+ MaxRetries *int
+
+ StopWhen []StopCondition
+ PrepareStep PrepareStepFunction
+ RepairToolCall RepairToolCallFunction
+
+ // Agent-level callbacks
+ OnAgentStart OnAgentStartFunc // Called when agent starts
+ OnAgentFinish OnAgentFinishFunc // Called when agent finishes
+ OnStepStart OnStepStartFunc // Called when a step starts
+ OnStepFinish OnStepFinishFunc // Called when a step finishes
+ OnFinish OnFinishFunc // Called when entire agent completes
+ OnError OnErrorFunc // Called when an error occurs
+
+ // Stream part callbacks - called for each corresponding stream part type
+ OnChunk OnChunkFunc // Called for each stream part (catch-all)
+ OnWarnings OnWarningsFunc // Called for warnings
+ OnTextStart OnTextStartFunc // Called when text starts
+ OnTextDelta OnTextDeltaFunc // Called for text deltas
+ OnTextEnd OnTextEndFunc // Called when text ends
+ OnReasoningStart OnReasoningStartFunc // Called when reasoning starts
+ OnReasoningDelta OnReasoningDeltaFunc // Called for reasoning deltas
+ OnReasoningEnd OnReasoningEndFunc // Called when reasoning ends
+ OnToolInputStart OnToolInputStartFunc // Called when tool input starts
+ OnToolInputDelta OnToolInputDeltaFunc // Called for tool input deltas
+ OnToolInputEnd OnToolInputEndFunc // Called when tool input ends
+ OnToolCall OnToolCallFunc // Called when tool call is complete
+ OnToolResult OnToolResultFunc // Called when tool execution completes
+ OnSource OnSourceFunc // Called for source references
+ OnStreamFinish OnStreamFinishFunc // Called when stream finishes
+}
+
+// AgentResult represents the result of an agent execution.
+type AgentResult struct {
+ Steps []StepResult
+ // Final response
+ Response Response
+ TotalUsage Usage
+}
+
+// Agent represents an AI agent that can generate responses and stream responses.
+type Agent interface {
+ Generate(context.Context, AgentCall) (*AgentResult, error)
+ Stream(context.Context, AgentStreamCall) (*AgentResult, error)
+}
+
+// AgentOption defines a function that configures agent settings.
+type AgentOption = func(*agentSettings)
+
+type agent struct {
+ settings agentSettings
+}
+
+// NewAgent creates a new agent with the given language model and options.
+func NewAgent(model LanguageModel, opts ...AgentOption) Agent {
+ settings := agentSettings{
+ model: model,
+ }
+ for _, o := range opts {
+ o(&settings)
+ }
+ return &agent{
+ settings: settings,
+ }
+}
+
+func (a *agent) prepareCall(call AgentCall) AgentCall {
+ call.MaxOutputTokens = cmp.Or(call.MaxOutputTokens, a.settings.maxOutputTokens)
+ call.Temperature = cmp.Or(call.Temperature, a.settings.temperature)
+ call.TopP = cmp.Or(call.TopP, a.settings.topP)
+ call.TopK = cmp.Or(call.TopK, a.settings.topK)
+ call.PresencePenalty = cmp.Or(call.PresencePenalty, a.settings.presencePenalty)
+ call.FrequencyPenalty = cmp.Or(call.FrequencyPenalty, a.settings.frequencyPenalty)
+ call.MaxRetries = cmp.Or(call.MaxRetries, a.settings.maxRetries)
+
+ if len(call.StopWhen) == 0 && len(a.settings.stopWhen) > 0 {
+ call.StopWhen = a.settings.stopWhen
+ }
+ if call.PrepareStep == nil && a.settings.prepareStep != nil {
+ call.PrepareStep = a.settings.prepareStep
+ }
+ if call.RepairToolCall == nil && a.settings.repairToolCall != nil {
+ call.RepairToolCall = a.settings.repairToolCall
+ }
+ if call.OnRetry == nil && a.settings.onRetry != nil {
+ call.OnRetry = a.settings.onRetry
+ }
+
+ providerOptions := ProviderOptions{}
+ if a.settings.providerOptions != nil {
+ maps.Copy(providerOptions, a.settings.providerOptions)
+ }
+ if call.ProviderOptions != nil {
+ maps.Copy(providerOptions, call.ProviderOptions)
+ }
+ call.ProviderOptions = providerOptions
+
+ headers := map[string]string{}
+
+ if a.settings.headers != nil {
+ maps.Copy(headers, a.settings.headers)
+ }
+
+ return call
+}
+
+// Generate implements Agent.
+func (a *agent) Generate(ctx context.Context, opts AgentCall) (*AgentResult, error) {
+ opts = a.prepareCall(opts)
+ initialPrompt, err := a.createPrompt(a.settings.systemPrompt, opts.Prompt, opts.Messages, opts.Files...)
+ if err != nil {
+ return nil, err
+ }
+ var responseMessages []Message
+ var steps []StepResult
+
+ for {
+ stepInputMessages := append(initialPrompt, responseMessages...)
+ stepModel := a.settings.model
+ stepSystemPrompt := a.settings.systemPrompt
+ stepActiveTools := opts.ActiveTools
+ stepToolChoice := ToolChoiceAuto
+ disableAllTools := false
+ stepTools := a.settings.tools
+ if opts.PrepareStep != nil {
+ updatedCtx, prepared, err := opts.PrepareStep(ctx, PrepareStepFunctionOptions{
+ Model: stepModel,
+ Steps: steps,
+ StepNumber: len(steps),
+ Messages: stepInputMessages,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ ctx = updatedCtx
+
+ // Apply prepared step modifications
+ if prepared.Messages != nil {
+ stepInputMessages = prepared.Messages
+ }
+ if prepared.Model != nil {
+ stepModel = prepared.Model
+ }
+ if prepared.System != nil {
+ stepSystemPrompt = *prepared.System
+ }
+ if prepared.ToolChoice != nil {
+ stepToolChoice = *prepared.ToolChoice
+ }
+ if len(prepared.ActiveTools) > 0 {
+ stepActiveTools = prepared.ActiveTools
+ }
+ disableAllTools = prepared.DisableAllTools
+ if prepared.Tools != nil {
+ stepTools = prepared.Tools
+ }
+ }
+
+ // Recreate prompt with potentially modified system prompt
+ if stepSystemPrompt != a.settings.systemPrompt {
+ stepPrompt, err := a.createPrompt(stepSystemPrompt, opts.Prompt, opts.Messages, opts.Files...)
+ if err != nil {
+ return nil, err
+ }
+ // Replace system message part, keep the rest
+ if len(stepInputMessages) > 0 && len(stepPrompt) > 0 {
+ stepInputMessages[0] = stepPrompt[0] // Replace system message
+ }
+ }
+
+ preparedTools := a.prepareTools(stepTools, stepActiveTools, disableAllTools)
+
+ retryOptions := DefaultRetryOptions()
+ if opts.MaxRetries != nil {
+ retryOptions.MaxRetries = *opts.MaxRetries
+ }
+ retryOptions.OnRetry = opts.OnRetry
+ retry := RetryWithExponentialBackoffRespectingRetryHeaders[*Response](retryOptions)
+
+ result, err := retry(ctx, func() (*Response, error) {
+ return stepModel.Generate(ctx, Call{
+ Prompt: stepInputMessages,
+ MaxOutputTokens: opts.MaxOutputTokens,
+ Temperature: opts.Temperature,
+ TopP: opts.TopP,
+ TopK: opts.TopK,
+ PresencePenalty: opts.PresencePenalty,
+ FrequencyPenalty: opts.FrequencyPenalty,
+ Tools: preparedTools,
+ ToolChoice: &stepToolChoice,
+ ProviderOptions: opts.ProviderOptions,
+ })
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ var stepToolCalls []ToolCallContent
+ for _, content := range result.Content {
+ if content.GetType() == ContentTypeToolCall {
+ toolCall, ok := AsContentType[ToolCallContent](content)
+ if !ok {
+ continue
+ }
+
+ // Validate and potentially repair the tool call
+ validatedToolCall := a.validateAndRepairToolCall(ctx, toolCall, stepTools, stepSystemPrompt, stepInputMessages, a.settings.repairToolCall)
+ stepToolCalls = append(stepToolCalls, validatedToolCall)
+ }
+ }
+
+ toolResults, err := a.executeTools(ctx, stepTools, stepToolCalls, nil)
+
+ // Build step content with validated tool calls and tool results
+ stepContent := []Content{}
+ toolCallIndex := 0
+ for _, content := range result.Content {
+ if content.GetType() == ContentTypeToolCall {
+ // Replace with validated tool call
+ if toolCallIndex < len(stepToolCalls) {
+ stepContent = append(stepContent, stepToolCalls[toolCallIndex])
+ toolCallIndex++
+ }
+ } else {
+ // Keep other content as-is
+ stepContent = append(stepContent, content)
+ }
+ }
+ // Add tool results
+ for _, result := range toolResults {
+ stepContent = append(stepContent, result)
+ }
+ currentStepMessages := toResponseMessages(stepContent)
+ responseMessages = append(responseMessages, currentStepMessages...)
+
+ stepResult := StepResult{
+ Response: Response{
+ Content: stepContent,
+ FinishReason: result.FinishReason,
+ Usage: result.Usage,
+ Warnings: result.Warnings,
+ ProviderMetadata: result.ProviderMetadata,
+ },
+ Messages: currentStepMessages,
+ }
+ steps = append(steps, stepResult)
+ shouldStop := isStopConditionMet(opts.StopWhen, steps)
+
+ if shouldStop || err != nil || len(stepToolCalls) == 0 || result.FinishReason != FinishReasonToolCalls {
+ break
+ }
+ }
+
+ totalUsage := Usage{}
+
+ for _, step := range steps {
+ usage := step.Usage
+ totalUsage.InputTokens += usage.InputTokens
+ totalUsage.OutputTokens += usage.OutputTokens
+ totalUsage.ReasoningTokens += usage.ReasoningTokens
+ totalUsage.CacheCreationTokens += usage.CacheCreationTokens
+ totalUsage.CacheReadTokens += usage.CacheReadTokens
+ totalUsage.TotalTokens += usage.TotalTokens
+ }
+
+ agentResult := &AgentResult{
+ Steps: steps,
+ Response: steps[len(steps)-1].Response,
+ TotalUsage: totalUsage,
+ }
+ return agentResult, nil
+}
+
+func isStopConditionMet(conditions []StopCondition, steps []StepResult) bool {
+ if len(conditions) == 0 {
+ return false
+ }
+
+ for _, condition := range conditions {
+ if condition(steps) {
+ return true
+ }
+ }
+ return false
+}
+
+func toResponseMessages(content []Content) []Message {
+ var assistantParts []MessagePart
+ var toolParts []MessagePart
+
+ for _, c := range content {
+ switch c.GetType() {
+ case ContentTypeText:
+ text, ok := AsContentType[TextContent](c)
+ if !ok {
+ continue
+ }
+ assistantParts = append(assistantParts, TextPart{
+ Text: text.Text,
+ ProviderOptions: ProviderOptions(text.ProviderMetadata),
+ })
+ case ContentTypeReasoning:
+ reasoning, ok := AsContentType[ReasoningContent](c)
+ if !ok {
+ continue
+ }
+ assistantParts = append(assistantParts, ReasoningPart{
+ Text: reasoning.Text,
+ ProviderOptions: ProviderOptions(reasoning.ProviderMetadata),
+ })
+ case ContentTypeToolCall:
+ toolCall, ok := AsContentType[ToolCallContent](c)
+ if !ok {
+ continue
+ }
+ assistantParts = append(assistantParts, ToolCallPart{
+ ToolCallID: toolCall.ToolCallID,
+ ToolName: toolCall.ToolName,
+ Input: toolCall.Input,
+ ProviderExecuted: toolCall.ProviderExecuted,
+ ProviderOptions: ProviderOptions(toolCall.ProviderMetadata),
+ })
+ case ContentTypeFile:
+ file, ok := AsContentType[FileContent](c)
+ if !ok {
+ continue
+ }
+ assistantParts = append(assistantParts, FilePart{
+ Data: file.Data,
+ MediaType: file.MediaType,
+ ProviderOptions: ProviderOptions(file.ProviderMetadata),
+ })
+ case ContentTypeSource:
+ // Sources are metadata about references used to generate the response.
+ // They don't need to be included in the conversation messages.
+ continue
+ case ContentTypeToolResult:
+ result, ok := AsContentType[ToolResultContent](c)
+ if !ok {
+ continue
+ }
+ toolParts = append(toolParts, ToolResultPart{
+ ToolCallID: result.ToolCallID,
+ Output: result.Result,
+ ProviderOptions: ProviderOptions(result.ProviderMetadata),
+ })
+ }
+ }
+
+ var messages []Message
+ if len(assistantParts) > 0 {
+ messages = append(messages, Message{
+ Role: MessageRoleAssistant,
+ Content: assistantParts,
+ })
+ }
+ if len(toolParts) > 0 {
+ messages = append(messages, Message{
+ Role: MessageRoleTool,
+ Content: toolParts,
+ })
+ }
+ return messages
+}
+
+func (a *agent) executeTools(ctx context.Context, allTools []AgentTool, toolCalls []ToolCallContent, toolResultCallback func(result ToolResultContent) error) ([]ToolResultContent, error) {
+ if len(toolCalls) == 0 {
+ return nil, nil
+ }
+
+ // Create a map for quick tool lookup
+ toolMap := make(map[string]AgentTool)
+ for _, tool := range allTools {
+ toolMap[tool.Info().Name] = tool
+ }
+
+ // Execute all tool calls sequentially in order
+ results := make([]ToolResultContent, 0, len(toolCalls))
+
+ for _, toolCall := range toolCalls {
+ result, isCriticalError := a.executeSingleTool(ctx, toolMap, toolCall, toolResultCallback)
+ results = append(results, result)
+ if isCriticalError {
+ if errorResult, ok := result.Result.(ToolResultOutputContentError); ok && errorResult.Error != nil {
+ return nil, errorResult.Error
+ }
+ }
+ }
+
+ return results, nil
+}
+
+// executeSingleTool executes a single tool and returns its result and a critical error flag.
+func (a *agent) executeSingleTool(ctx context.Context, toolMap map[string]AgentTool, toolCall ToolCallContent, toolResultCallback func(result ToolResultContent) error) (ToolResultContent, bool) {
+ result := ToolResultContent{
+ ToolCallID: toolCall.ToolCallID,
+ ToolName: toolCall.ToolName,
+ ProviderExecuted: false,
+ }
+
+ // Skip invalid tool calls - create error result (not critical)
+ if toolCall.Invalid {
+ result.Result = ToolResultOutputContentError{
+ Error: toolCall.ValidationError,
+ }
+ if toolResultCallback != nil {
+ _ = toolResultCallback(result)
+ }
+ return result, false
+ }
+
+ tool, exists := toolMap[toolCall.ToolName]
+ if !exists {
+ result.Result = ToolResultOutputContentError{
+ Error: errors.New("Error: Tool not found: " + toolCall.ToolName),
+ }
+ if toolResultCallback != nil {
+ _ = toolResultCallback(result)
+ }
+ return result, false
+ }
+
+ // Execute the tool
+ toolResult, err := tool.Run(ctx, ToolCall{
+ ID: toolCall.ToolCallID,
+ Name: toolCall.ToolName,
+ Input: toolCall.Input,
+ })
+ if err != nil {
+ result.Result = ToolResultOutputContentError{
+ Error: err,
+ }
+ result.ClientMetadata = toolResult.Metadata
+ if toolResultCallback != nil {
+ _ = toolResultCallback(result)
+ }
+ return result, true
+ }
+
+ result.ClientMetadata = toolResult.Metadata
+ if toolResult.IsError {
+ result.Result = ToolResultOutputContentError{
+ Error: errors.New(toolResult.Content),
+ }
+ } else if toolResult.Type == "image" || toolResult.Type == "media" {
+ result.Result = ToolResultOutputContentMedia{
+ Data: string(toolResult.Data),
+ MediaType: toolResult.MediaType,
+ Text: toolResult.Content,
+ }
+ } else {
+ result.Result = ToolResultOutputContentText{
+ Text: toolResult.Content,
+ }
+ }
+ if toolResultCallback != nil {
+ _ = toolResultCallback(result)
+ }
+ return result, false
+}
+
+// Stream implements Agent.
+func (a *agent) Stream(ctx context.Context, opts AgentStreamCall) (*AgentResult, error) {
+ // Convert AgentStreamCall to AgentCall for preparation
+ call := AgentCall{
+ Prompt: opts.Prompt,
+ Files: opts.Files,
+ Messages: opts.Messages,
+ MaxOutputTokens: opts.MaxOutputTokens,
+ Temperature: opts.Temperature,
+ TopP: opts.TopP,
+ TopK: opts.TopK,
+ PresencePenalty: opts.PresencePenalty,
+ FrequencyPenalty: opts.FrequencyPenalty,
+ ActiveTools: opts.ActiveTools,
+ ProviderOptions: opts.ProviderOptions,
+ MaxRetries: opts.MaxRetries,
+ OnRetry: opts.OnRetry,
+ StopWhen: opts.StopWhen,
+ PrepareStep: opts.PrepareStep,
+ RepairToolCall: opts.RepairToolCall,
+ }
+
+ call = a.prepareCall(call)
+
+ initialPrompt, err := a.createPrompt(a.settings.systemPrompt, call.Prompt, call.Messages, call.Files...)
+ if err != nil {
+ return nil, err
+ }
+
+ var responseMessages []Message
+ var steps []StepResult
+ var totalUsage Usage
+
+ // Start agent stream
+ if opts.OnAgentStart != nil {
+ opts.OnAgentStart()
+ }
+
+ for stepNumber := 0; ; stepNumber++ {
+ stepInputMessages := append(initialPrompt, responseMessages...)
+ stepModel := a.settings.model
+ stepSystemPrompt := a.settings.systemPrompt
+ stepActiveTools := call.ActiveTools
+ stepToolChoice := ToolChoiceAuto
+ disableAllTools := false
+ stepTools := a.settings.tools
+ // Apply step preparation if provided
+ if call.PrepareStep != nil {
+ updatedCtx, prepared, err := call.PrepareStep(ctx, PrepareStepFunctionOptions{
+ Model: stepModel,
+ Steps: steps,
+ StepNumber: stepNumber,
+ Messages: stepInputMessages,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ ctx = updatedCtx
+
+ if prepared.Messages != nil {
+ stepInputMessages = prepared.Messages
+ }
+ if prepared.Model != nil {
+ stepModel = prepared.Model
+ }
+ if prepared.System != nil {
+ stepSystemPrompt = *prepared.System
+ }
+ if prepared.ToolChoice != nil {
+ stepToolChoice = *prepared.ToolChoice
+ }
+ if len(prepared.ActiveTools) > 0 {
+ stepActiveTools = prepared.ActiveTools
+ }
+ disableAllTools = prepared.DisableAllTools
+ if prepared.Tools != nil {
+ stepTools = prepared.Tools
+ }
+ }
+
+ // Recreate prompt with potentially modified system prompt
+ if stepSystemPrompt != a.settings.systemPrompt {
+ stepPrompt, err := a.createPrompt(stepSystemPrompt, call.Prompt, call.Messages, call.Files...)
+ if err != nil {
+ return nil, err
+ }
+ if len(stepInputMessages) > 0 && len(stepPrompt) > 0 {
+ stepInputMessages[0] = stepPrompt[0]
+ }
+ }
+
+ preparedTools := a.prepareTools(stepTools, stepActiveTools, disableAllTools)
+
+ // Start step stream
+ if opts.OnStepStart != nil {
+ _ = opts.OnStepStart(stepNumber)
+ }
+
+ // Create streaming call
+ streamCall := Call{
+ Prompt: stepInputMessages,
+ MaxOutputTokens: call.MaxOutputTokens,
+ Temperature: call.Temperature,
+ TopP: call.TopP,
+ TopK: call.TopK,
+ PresencePenalty: call.PresencePenalty,
+ FrequencyPenalty: call.FrequencyPenalty,
+ Tools: preparedTools,
+ ToolChoice: &stepToolChoice,
+ ProviderOptions: call.ProviderOptions,
+ }
+
+ // Execute step with retry logic wrapping both stream creation and processing
+ retryOptions := DefaultRetryOptions()
+ if call.MaxRetries != nil {
+ retryOptions.MaxRetries = *call.MaxRetries
+ }
+ retryOptions.OnRetry = call.OnRetry
+ retry := RetryWithExponentialBackoffRespectingRetryHeaders[stepExecutionResult](retryOptions)
+
+ result, err := retry(ctx, func() (stepExecutionResult, error) {
+ // Create the stream
+ stream, err := stepModel.Stream(ctx, streamCall)
+ if err != nil {
+ return stepExecutionResult{}, err
+ }
+
+ // Process the stream
+ result, err := a.processStepStream(ctx, stream, opts, steps, stepTools)
+ if err != nil {
+ return stepExecutionResult{}, err
+ }
+
+ return result, nil
+ })
+ if err != nil {
+ if opts.OnError != nil {
+ opts.OnError(err)
+ }
+ return nil, err
+ }
+
+ steps = append(steps, result.StepResult)
+ totalUsage = addUsage(totalUsage, result.StepResult.Usage)
+
+ // Call step finished callback
+ if opts.OnStepFinish != nil {
+ _ = opts.OnStepFinish(result.StepResult)
+ }
+
+ // Add step messages to response messages
+ stepMessages := toResponseMessages(result.StepResult.Content)
+ responseMessages = append(responseMessages, stepMessages...)
+
+ // Check stop conditions
+ shouldStop := isStopConditionMet(call.StopWhen, steps)
+ if shouldStop || !result.ShouldContinue {
+ break
+ }
+ }
+
+ // Finish agent stream
+ agentResult := &AgentResult{
+ Steps: steps,
+ Response: steps[len(steps)-1].Response,
+ TotalUsage: totalUsage,
+ }
+
+ if opts.OnFinish != nil {
+ opts.OnFinish(agentResult)
+ }
+
+ if opts.OnAgentFinish != nil {
+ _ = opts.OnAgentFinish(agentResult)
+ }
+
+ return agentResult, nil
+}
+
+func (a *agent) prepareTools(tools []AgentTool, activeTools []string, disableAllTools bool) []Tool {
+ preparedTools := make([]Tool, 0, len(tools))
+
+ // If explicitly disabling all tools, return no tools
+ if disableAllTools {
+ return preparedTools
+ }
+
+ for _, tool := range tools {
+ // If activeTools has items, only include tools in the list
+ // If activeTools is empty, include all tools
+ if len(activeTools) > 0 && !slices.Contains(activeTools, tool.Info().Name) {
+ continue
+ }
+ info := tool.Info()
+ inputSchema := map[string]any{
+ "type": "object",
+ "properties": info.Parameters,
+ "required": info.Required,
+ }
+ schema.Normalize(inputSchema)
+ preparedTools = append(preparedTools, FunctionTool{
+ Name: info.Name,
+ Description: info.Description,
+ InputSchema: inputSchema,
+ ProviderOptions: tool.ProviderOptions(),
+ })
+ }
+ return preparedTools
+}
+
+// validateAndRepairToolCall validates a tool call and attempts repair if validation fails.
+func (a *agent) validateAndRepairToolCall(ctx context.Context, toolCall ToolCallContent, availableTools []AgentTool, systemPrompt string, messages []Message, repairFunc RepairToolCallFunction) ToolCallContent {
+ if err := a.validateToolCall(toolCall, availableTools); err == nil {
+ return toolCall
+ } else { //nolint: revive
+ if repairFunc != nil {
+ repairOptions := ToolCallRepairOptions{
+ OriginalToolCall: toolCall,
+ ValidationError: err,
+ AvailableTools: availableTools,
+ SystemPrompt: systemPrompt,
+ Messages: messages,
+ }
+
+ if repairedToolCall, repairErr := repairFunc(ctx, repairOptions); repairErr == nil && repairedToolCall != nil {
+ if validateErr := a.validateToolCall(*repairedToolCall, availableTools); validateErr == nil {
+ return *repairedToolCall
+ }
+ }
+ }
+
+ invalidToolCall := toolCall
+ invalidToolCall.Invalid = true
+ invalidToolCall.ValidationError = err
+ return invalidToolCall
+ }
+}
+
+// validateToolCall validates a tool call against available tools and their schemas.
+func (a *agent) validateToolCall(toolCall ToolCallContent, availableTools []AgentTool) error {
+ var tool AgentTool
+ for _, t := range availableTools {
+ if t.Info().Name == toolCall.ToolName {
+ tool = t
+ break
+ }
+ }
+
+ if tool == nil {
+ return fmt.Errorf("tool not found: %s", toolCall.ToolName)
+ }
+
+ // Validate JSON parsing
+ var input map[string]any
+ if err := json.Unmarshal([]byte(toolCall.Input), &input); err != nil {
+ return fmt.Errorf("invalid JSON input: %w", err)
+ }
+
+ // Basic schema validation (check required fields)
+ // TODO: more robust schema validation using JSON Schema or similar
+ toolInfo := tool.Info()
+ for _, required := range toolInfo.Required {
+ if _, exists := input[required]; !exists {
+ return fmt.Errorf("missing required parameter: %s", required)
+ }
+ }
+ return nil
+}
+
+func (a *agent) createPrompt(system, prompt string, messages []Message, files ...FilePart) (Prompt, error) {
+ if prompt == "" {
+ return nil, &Error{Title: "invalid argument", Message: "prompt can't be empty"}
+ }
+
+ var preparedPrompt Prompt
+
+ if system != "" {
+ preparedPrompt = append(preparedPrompt, NewSystemMessage(system))
+ }
+ preparedPrompt = append(preparedPrompt, messages...)
+ preparedPrompt = append(preparedPrompt, NewUserMessage(prompt, files...))
+ return preparedPrompt, nil
+}
+
+// WithSystemPrompt sets the system prompt for the agent.
+func WithSystemPrompt(prompt string) AgentOption {
+ return func(s *agentSettings) {
+ s.systemPrompt = prompt
+ }
+}
+
+// WithMaxOutputTokens sets the maximum output tokens for the agent.
+func WithMaxOutputTokens(tokens int64) AgentOption {
+ return func(s *agentSettings) {
+ s.maxOutputTokens = &tokens
+ }
+}
+
+// WithTemperature sets the temperature for the agent.
+func WithTemperature(temp float64) AgentOption {
+ return func(s *agentSettings) {
+ s.temperature = &temp
+ }
+}
+
+// WithTopP sets the top-p value for the agent.
+func WithTopP(topP float64) AgentOption {
+ return func(s *agentSettings) {
+ s.topP = &topP
+ }
+}
+
+// WithTopK sets the top-k value for the agent.
+func WithTopK(topK int64) AgentOption {
+ return func(s *agentSettings) {
+ s.topK = &topK
+ }
+}
+
+// WithPresencePenalty sets the presence penalty for the agent.
+func WithPresencePenalty(penalty float64) AgentOption {
+ return func(s *agentSettings) {
+ s.presencePenalty = &penalty
+ }
+}
+
+// WithFrequencyPenalty sets the frequency penalty for the agent.
+func WithFrequencyPenalty(penalty float64) AgentOption {
+ return func(s *agentSettings) {
+ s.frequencyPenalty = &penalty
+ }
+}
+
+// WithTools sets the tools for the agent.
+func WithTools(tools ...AgentTool) AgentOption {
+ return func(s *agentSettings) {
+ s.tools = append(s.tools, tools...)
+ }
+}
+
+// WithStopConditions sets the stop conditions for the agent.
+func WithStopConditions(conditions ...StopCondition) AgentOption {
+ return func(s *agentSettings) {
+ s.stopWhen = append(s.stopWhen, conditions...)
+ }
+}
+
+// WithPrepareStep sets the prepare step function for the agent.
+func WithPrepareStep(fn PrepareStepFunction) AgentOption {
+ return func(s *agentSettings) {
+ s.prepareStep = fn
+ }
+}
+
+// WithRepairToolCall sets the repair tool call function for the agent.
+func WithRepairToolCall(fn RepairToolCallFunction) AgentOption {
+ return func(s *agentSettings) {
+ s.repairToolCall = fn
+ }
+}
+
+// WithMaxRetries sets the maximum number of retries for the agent.
+func WithMaxRetries(maxRetries int) AgentOption {
+ return func(s *agentSettings) {
+ s.maxRetries = &maxRetries
+ }
+}
+
+// WithOnRetry sets the retry callback for the agent.
+func WithOnRetry(callback OnRetryCallback) AgentOption {
+ return func(s *agentSettings) {
+ s.onRetry = callback
+ }
+}
+
+// processStepStream processes a single step's stream and returns the step result.
+func (a *agent) processStepStream(ctx context.Context, stream StreamResponse, opts AgentStreamCall, _ []StepResult, stepTools []AgentTool) (stepExecutionResult, error) {
+ var stepContent []Content
+ var stepToolCalls []ToolCallContent
+ var stepUsage Usage
+ stepFinishReason := FinishReasonUnknown
+ var stepWarnings []CallWarning
+ var stepProviderMetadata ProviderMetadata
+
+ activeToolCalls := make(map[string]*ToolCallContent)
+ activeTextContent := make(map[string]string)
+ type reasoningContent struct {
+ content string
+ options ProviderMetadata
+ }
+ activeReasoningContent := make(map[string]reasoningContent)
+
+ // Set up concurrent tool execution
+ type toolExecutionRequest struct {
+ toolCall ToolCallContent
+ parallel bool
+ }
+ toolChan := make(chan toolExecutionRequest, 10)
+ var toolExecutionWg sync.WaitGroup
+ var toolStateMu sync.Mutex
+ toolResults := make([]ToolResultContent, 0)
+ var toolExecutionErr error
+
+ // Create a map for quick tool lookup
+ toolMap := make(map[string]AgentTool)
+ for _, tool := range stepTools {
+ toolMap[tool.Info().Name] = tool
+ }
+
+ // Semaphores for controlling parallelism
+ parallelSem := make(chan struct{}, 5)
+ var sequentialMu sync.Mutex
+
+ // Single coordinator goroutine that dispatches tools
+ toolExecutionWg.Go(func() {
+ for req := range toolChan {
+ if req.parallel {
+ parallelSem <- struct{}{}
+ toolExecutionWg.Go(func() {
+ defer func() { <-parallelSem }()
+ result, isCriticalError := a.executeSingleTool(ctx, toolMap, req.toolCall, opts.OnToolResult)
+ toolStateMu.Lock()
+ toolResults = append(toolResults, result)
+ if isCriticalError && toolExecutionErr == nil {
+ if errorResult, ok := result.Result.(ToolResultOutputContentError); ok && errorResult.Error != nil {
+ toolExecutionErr = errorResult.Error
+ }
+ }
+ toolStateMu.Unlock()
+ })
+ } else {
+ sequentialMu.Lock()
+ result, isCriticalError := a.executeSingleTool(ctx, toolMap, req.toolCall, opts.OnToolResult)
+ toolStateMu.Lock()
+ toolResults = append(toolResults, result)
+ if isCriticalError && toolExecutionErr == nil {
+ if errorResult, ok := result.Result.(ToolResultOutputContentError); ok && errorResult.Error != nil {
+ toolExecutionErr = errorResult.Error
+ }
+ }
+ toolStateMu.Unlock()
+ sequentialMu.Unlock()
+ }
+ }
+ })
+
+ // Process stream parts
+ for part := range stream {
+ // Forward all parts to chunk callback
+ if opts.OnChunk != nil {
+ err := opts.OnChunk(part)
+ if err != nil {
+ return stepExecutionResult{}, err
+ }
+ }
+
+ switch part.Type {
+ case StreamPartTypeWarnings:
+ stepWarnings = part.Warnings
+ if opts.OnWarnings != nil {
+ err := opts.OnWarnings(part.Warnings)
+ if err != nil {
+ return stepExecutionResult{}, err
+ }
+ }
+
+ case StreamPartTypeTextStart:
+ activeTextContent[part.ID] = ""
+ if opts.OnTextStart != nil {
+ err := opts.OnTextStart(part.ID)
+ if err != nil {
+ return stepExecutionResult{}, err
+ }
+ }
+
+ case StreamPartTypeTextDelta:
+ if _, exists := activeTextContent[part.ID]; exists {
+ activeTextContent[part.ID] += part.Delta
+ }
+ if opts.OnTextDelta != nil {
+ err := opts.OnTextDelta(part.ID, part.Delta)
+ if err != nil {
+ return stepExecutionResult{}, err
+ }
+ }
+
+ case StreamPartTypeTextEnd:
+ if text, exists := activeTextContent[part.ID]; exists {
+ stepContent = append(stepContent, TextContent{
+ Text: text,
+ ProviderMetadata: part.ProviderMetadata,
+ })
+ delete(activeTextContent, part.ID)
+ }
+ if opts.OnTextEnd != nil {
+ err := opts.OnTextEnd(part.ID)
+ if err != nil {
+ return stepExecutionResult{}, err
+ }
+ }
+
+ case StreamPartTypeReasoningStart:
+ activeReasoningContent[part.ID] = reasoningContent{content: part.Delta, options: part.ProviderMetadata}
+ if opts.OnReasoningStart != nil {
+ content := ReasoningContent{
+ Text: part.Delta,
+ ProviderMetadata: part.ProviderMetadata,
+ }
+ err := opts.OnReasoningStart(part.ID, content)
+ if err != nil {
+ return stepExecutionResult{}, err
+ }
+ }
+
+ case StreamPartTypeReasoningDelta:
+ if active, exists := activeReasoningContent[part.ID]; exists {
+ active.content += part.Delta
+ active.options = part.ProviderMetadata
+ activeReasoningContent[part.ID] = active
+ }
+ if opts.OnReasoningDelta != nil {
+ err := opts.OnReasoningDelta(part.ID, part.Delta)
+ if err != nil {
+ return stepExecutionResult{}, err
+ }
+ }
+
+ case StreamPartTypeReasoningEnd:
+ if active, exists := activeReasoningContent[part.ID]; exists {
+ if part.ProviderMetadata != nil {
+ active.options = part.ProviderMetadata
+ }
+ content := ReasoningContent{
+ Text: active.content,
+ ProviderMetadata: active.options,
+ }
+ stepContent = append(stepContent, content)
+ if opts.OnReasoningEnd != nil {
+ err := opts.OnReasoningEnd(part.ID, content)
+ if err != nil {
+ return stepExecutionResult{}, err
+ }
+ }
+ delete(activeReasoningContent, part.ID)
+ }
+
+ case StreamPartTypeToolInputStart:
+ activeToolCalls[part.ID] = &ToolCallContent{
+ ToolCallID: part.ID,
+ ToolName: part.ToolCallName,
+ Input: "",
+ ProviderExecuted: part.ProviderExecuted,
+ }
+ if opts.OnToolInputStart != nil {
+ err := opts.OnToolInputStart(part.ID, part.ToolCallName)
+ if err != nil {
+ return stepExecutionResult{}, err
+ }
+ }
+
+ case StreamPartTypeToolInputDelta:
+ if toolCall, exists := activeToolCalls[part.ID]; exists {
+ toolCall.Input += part.Delta
+ }
+ if opts.OnToolInputDelta != nil {
+ err := opts.OnToolInputDelta(part.ID, part.Delta)
+ if err != nil {
+ return stepExecutionResult{}, err
+ }
+ }
+
+ case StreamPartTypeToolInputEnd:
+ if opts.OnToolInputEnd != nil {
+ err := opts.OnToolInputEnd(part.ID)
+ if err != nil {
+ return stepExecutionResult{}, err
+ }
+ }
+
+ case StreamPartTypeToolCall:
+ toolCall := ToolCallContent{
+ ToolCallID: part.ID,
+ ToolName: part.ToolCallName,
+ Input: part.ToolCallInput,
+ ProviderExecuted: part.ProviderExecuted,
+ ProviderMetadata: part.ProviderMetadata,
+ }
+
+ // Validate and potentially repair the tool call
+ validatedToolCall := a.validateAndRepairToolCall(ctx, toolCall, stepTools, a.settings.systemPrompt, nil, opts.RepairToolCall)
+ stepToolCalls = append(stepToolCalls, validatedToolCall)
+ stepContent = append(stepContent, validatedToolCall)
+
+ if opts.OnToolCall != nil {
+ err := opts.OnToolCall(validatedToolCall)
+ if err != nil {
+ return stepExecutionResult{}, err
+ }
+ }
+
+ // Determine if tool can run in parallel
+ isParallel := false
+ if tool, exists := toolMap[validatedToolCall.ToolName]; exists {
+ isParallel = tool.Info().Parallel
+ }
+
+ // Send tool call to execution channel
+ toolChan <- toolExecutionRequest{toolCall: validatedToolCall, parallel: isParallel}
+
+ // Clean up active tool call
+ delete(activeToolCalls, part.ID)
+
+ case StreamPartTypeSource:
+ sourceContent := SourceContent{
+ SourceType: part.SourceType,
+ ID: part.ID,
+ URL: part.URL,
+ Title: part.Title,
+ ProviderMetadata: part.ProviderMetadata,
+ }
+ stepContent = append(stepContent, sourceContent)
+ if opts.OnSource != nil {
+ err := opts.OnSource(sourceContent)
+ if err != nil {
+ return stepExecutionResult{}, err
+ }
+ }
+
+ case StreamPartTypeFinish:
+ stepUsage = part.Usage
+ stepFinishReason = part.FinishReason
+ stepProviderMetadata = part.ProviderMetadata
+ if opts.OnStreamFinish != nil {
+ err := opts.OnStreamFinish(part.Usage, part.FinishReason, part.ProviderMetadata)
+ if err != nil {
+ return stepExecutionResult{}, err
+ }
+ }
+
+ case StreamPartTypeError:
+ return stepExecutionResult{}, part.Error
+ }
+ }
+
+ // Close the tool execution channel and wait for all executions to complete
+ close(toolChan)
+ toolExecutionWg.Wait()
+
+ // Check for tool execution errors
+ if toolExecutionErr != nil {
+ return stepExecutionResult{}, toolExecutionErr
+ }
+
+ // Add tool results to content if any
+ if len(toolResults) > 0 {
+ for _, result := range toolResults {
+ stepContent = append(stepContent, result)
+ }
+ }
+
+ stepResult := StepResult{
+ Response: Response{
+ Content: stepContent,
+ FinishReason: stepFinishReason,
+ Usage: stepUsage,
+ Warnings: stepWarnings,
+ ProviderMetadata: stepProviderMetadata,
+ },
+ Messages: toResponseMessages(stepContent),
+ }
+
+ // Determine if we should continue (has tool calls and not stopped)
+ shouldContinue := len(stepToolCalls) > 0 && stepFinishReason == FinishReasonToolCalls
+
+ return stepExecutionResult{
+ StepResult: stepResult,
+ ShouldContinue: shouldContinue,
+ }, nil
+}
+
+func addUsage(a, b Usage) Usage {
+ return Usage{
+ InputTokens: a.InputTokens + b.InputTokens,
+ OutputTokens: a.OutputTokens + b.OutputTokens,
+ TotalTokens: a.TotalTokens + b.TotalTokens,
+ ReasoningTokens: a.ReasoningTokens + b.ReasoningTokens,
+ CacheCreationTokens: a.CacheCreationTokens + b.CacheCreationTokens,
+ CacheReadTokens: a.CacheReadTokens + b.CacheReadTokens,
+ }
+}
+
+// WithHeaders sets the headers for the agent.
+func WithHeaders(headers map[string]string) AgentOption {
+ return func(s *agentSettings) {
+ s.headers = headers
+ }
+}
+
+// WithProviderOptions sets the provider options for the agent.
+func WithProviderOptions(providerOptions ProviderOptions) AgentOption {
+ return func(s *agentSettings) {
+ s.providerOptions = providerOptions
+ }
+}
diff --git a/internal/fantasy/agent_stream_test.go b/internal/fantasy/agent_stream_test.go
new file mode 100644
index 000000000..ea9009305
--- /dev/null
+++ b/internal/fantasy/agent_stream_test.go
@@ -0,0 +1,597 @@
+package fantasy
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+// EchoTool is a simple tool that echoes back the input message
+type EchoTool struct {
+ providerOptions ProviderOptions
+}
+
+func (e *EchoTool) SetProviderOptions(opts ProviderOptions) {
+ e.providerOptions = opts
+}
+
+func (e *EchoTool) ProviderOptions() ProviderOptions {
+ return e.providerOptions
+}
+
+// Info returns the tool information
+func (e *EchoTool) Info() ToolInfo {
+ return ToolInfo{
+ Name: "echo",
+ Description: "Echo back the provided message",
+ Parameters: map[string]any{
+ "message": map[string]any{
+ "type": "string",
+ "description": "The message to echo back",
+ },
+ },
+ Required: []string{"message"},
+ }
+}
+
+// Run executes the echo tool
+func (e *EchoTool) Run(ctx context.Context, params ToolCall) (ToolResponse, error) {
+ var input struct {
+ Message string `json:"message"`
+ }
+
+ if err := json.Unmarshal([]byte(params.Input), &input); err != nil {
+ return NewTextErrorResponse("Invalid input: " + err.Error()), nil
+ }
+
+ if input.Message == "" {
+ return NewTextErrorResponse("Message cannot be empty"), nil
+ }
+
+ return NewTextResponse("Echo: " + input.Message), nil
+}
+
+// TestStreamingAgentCallbacks tests that all streaming callbacks are called correctly
+func TestStreamingAgentCallbacks(t *testing.T) {
+ t.Parallel()
+
+ // Track which callbacks were called
+ callbacks := make(map[string]bool)
+
+ // Create a mock language model that returns various stream parts
+ mockModel := &mockLanguageModel{
+ streamFunc: func(ctx context.Context, call Call) (StreamResponse, error) {
+ return func(yield func(StreamPart) bool) {
+ // Test all stream part types
+ if !yield(StreamPart{Type: StreamPartTypeWarnings, Warnings: []CallWarning{{Type: CallWarningTypeOther, Message: "test warning"}}}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeTextStart, ID: "text-1"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeTextDelta, ID: "text-1", Delta: "Hello"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeTextEnd, ID: "text-1"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeReasoningStart, ID: "reasoning-1"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeReasoningDelta, ID: "reasoning-1", Delta: "thinking..."}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeReasoningEnd, ID: "reasoning-1"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeToolInputStart, ID: "tool-1", ToolCallName: "test_tool"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeToolInputDelta, ID: "tool-1", Delta: `{"param"`}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeToolInputEnd, ID: "tool-1"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeSource, ID: "source-1", SourceType: SourceTypeURL, URL: "https://example.com", Title: "Example"}) {
+ return
+ }
+ yield(StreamPart{
+ Type: StreamPartTypeFinish,
+ Usage: Usage{InputTokens: 5, OutputTokens: 2, TotalTokens: 7},
+ FinishReason: FinishReasonStop,
+ })
+ }, nil
+ },
+ }
+
+ // Create agent
+ agent := NewAgent(mockModel)
+
+ ctx := context.Background()
+
+ // Create streaming call with all callbacks
+ streamCall := AgentStreamCall{
+ Prompt: "Test all callbacks",
+ OnAgentStart: func() {
+ callbacks["OnAgentStart"] = true
+ },
+ OnAgentFinish: func(result *AgentResult) error {
+ callbacks["OnAgentFinish"] = true
+ return nil
+ },
+ OnStepStart: func(stepNumber int) error {
+ callbacks["OnStepStart"] = true
+ return nil
+ },
+ OnStepFinish: func(stepResult StepResult) error {
+ callbacks["OnStepFinish"] = true
+ return nil
+ },
+ OnFinish: func(result *AgentResult) {
+ callbacks["OnFinish"] = true
+ },
+ OnError: func(err error) {
+ callbacks["OnError"] = true
+ },
+ OnChunk: func(part StreamPart) error {
+ callbacks["OnChunk"] = true
+ return nil
+ },
+ OnWarnings: func(warnings []CallWarning) error {
+ callbacks["OnWarnings"] = true
+ return nil
+ },
+ OnTextStart: func(id string) error {
+ callbacks["OnTextStart"] = true
+ return nil
+ },
+ OnTextDelta: func(id, text string) error {
+ callbacks["OnTextDelta"] = true
+ return nil
+ },
+ OnTextEnd: func(id string) error {
+ callbacks["OnTextEnd"] = true
+ return nil
+ },
+ OnReasoningStart: func(id string, _ ReasoningContent) error {
+ callbacks["OnReasoningStart"] = true
+ return nil
+ },
+ OnReasoningDelta: func(id, text string) error {
+ callbacks["OnReasoningDelta"] = true
+ return nil
+ },
+ OnReasoningEnd: func(id string, content ReasoningContent) error {
+ callbacks["OnReasoningEnd"] = true
+ return nil
+ },
+ OnToolInputStart: func(id, toolName string) error {
+ callbacks["OnToolInputStart"] = true
+ return nil
+ },
+ OnToolInputDelta: func(id, delta string) error {
+ callbacks["OnToolInputDelta"] = true
+ return nil
+ },
+ OnToolInputEnd: func(id string) error {
+ callbacks["OnToolInputEnd"] = true
+ return nil
+ },
+ OnToolCall: func(toolCall ToolCallContent) error {
+ callbacks["OnToolCall"] = true
+ return nil
+ },
+ OnToolResult: func(result ToolResultContent) error {
+ callbacks["OnToolResult"] = true
+ return nil
+ },
+ OnSource: func(source SourceContent) error {
+ callbacks["OnSource"] = true
+ return nil
+ },
+ OnStreamFinish: func(usage Usage, finishReason FinishReason, providerMetadata ProviderMetadata) error {
+ callbacks["OnStreamFinish"] = true
+ return nil
+ },
+ }
+
+ // Execute streaming agent
+ result, err := agent.Stream(ctx, streamCall)
+ require.NoError(t, err)
+ require.NotNil(t, result)
+
+ // Verify that expected callbacks were called
+ expectedCallbacks := []string{
+ "OnAgentStart",
+ "OnAgentFinish",
+ "OnStepStart",
+ "OnStepFinish",
+ "OnFinish",
+ "OnChunk",
+ "OnWarnings",
+ "OnTextStart",
+ "OnTextDelta",
+ "OnTextEnd",
+ "OnReasoningStart",
+ "OnReasoningDelta",
+ "OnReasoningEnd",
+ "OnToolInputStart",
+ "OnToolInputDelta",
+ "OnToolInputEnd",
+ "OnSource",
+ "OnStreamFinish",
+ }
+
+ for _, callback := range expectedCallbacks {
+ require.True(t, callbacks[callback], "Expected callback %s to be called", callback)
+ }
+
+ // Verify that error callbacks were not called
+ require.False(t, callbacks["OnError"], "OnError should not be called in successful case")
+ require.False(t, callbacks["OnToolCall"], "OnToolCall should not be called without actual tool calls")
+ require.False(t, callbacks["OnToolResult"], "OnToolResult should not be called without actual tool results")
+}
+
+// TestStreamingAgentWithTools tests streaming agent with tool calls (mirrors TS test patterns)
+func TestStreamingAgentWithTools(t *testing.T) {
+ t.Parallel()
+
+ stepCount := 0
+ // Create a mock language model that makes a tool call then finishes
+ mockModel := &mockLanguageModel{
+ streamFunc: func(ctx context.Context, call Call) (StreamResponse, error) {
+ stepCount++
+ return func(yield func(StreamPart) bool) {
+ if stepCount == 1 {
+ // First step: make tool call
+ if !yield(StreamPart{Type: StreamPartTypeToolInputStart, ID: "tool-1", ToolCallName: "echo"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeToolInputDelta, ID: "tool-1", Delta: `{"message"`}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeToolInputDelta, ID: "tool-1", Delta: `: "test"}`}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeToolInputEnd, ID: "tool-1"}) {
+ return
+ }
+ if !yield(StreamPart{
+ Type: StreamPartTypeToolCall,
+ ID: "tool-1",
+ ToolCallName: "echo",
+ ToolCallInput: `{"message": "test"}`,
+ }) {
+ return
+ }
+ yield(StreamPart{
+ Type: StreamPartTypeFinish,
+ Usage: Usage{InputTokens: 10, OutputTokens: 5, TotalTokens: 15},
+ FinishReason: FinishReasonToolCalls,
+ })
+ } else {
+ // Second step: finish after tool execution
+ if !yield(StreamPart{Type: StreamPartTypeTextStart, ID: "text-1"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeTextDelta, ID: "text-1", Delta: "Tool executed successfully"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeTextEnd, ID: "text-1"}) {
+ return
+ }
+ yield(StreamPart{
+ Type: StreamPartTypeFinish,
+ Usage: Usage{InputTokens: 5, OutputTokens: 3, TotalTokens: 8},
+ FinishReason: FinishReasonStop,
+ })
+ }
+ }, nil
+ },
+ }
+
+ // Create agent with echo tool
+ agent := NewAgent(
+ mockModel,
+ WithSystemPrompt("You are a helpful assistant."),
+ WithTools(&EchoTool{}),
+ )
+
+ ctx := context.Background()
+
+ // Track callback invocations
+ var toolInputStartCalled bool
+ var toolInputDeltaCalled bool
+ var toolInputEndCalled bool
+ var toolCallCalled bool
+ var toolResultCalled bool
+
+ // Create streaming call with callbacks
+ streamCall := AgentStreamCall{
+ Prompt: "Echo 'test'",
+ OnToolInputStart: func(id, toolName string) error {
+ toolInputStartCalled = true
+ require.Equal(t, "tool-1", id)
+ require.Equal(t, "echo", toolName)
+ return nil
+ },
+ OnToolInputDelta: func(id, delta string) error {
+ toolInputDeltaCalled = true
+ require.Equal(t, "tool-1", id)
+ require.Contains(t, []string{`{"message"`, `: "test"}`}, delta)
+ return nil
+ },
+ OnToolInputEnd: func(id string) error {
+ toolInputEndCalled = true
+ require.Equal(t, "tool-1", id)
+ return nil
+ },
+ OnToolCall: func(toolCall ToolCallContent) error {
+ toolCallCalled = true
+ require.Equal(t, "echo", toolCall.ToolName)
+ require.Equal(t, `{"message": "test"}`, toolCall.Input)
+ return nil
+ },
+ OnToolResult: func(result ToolResultContent) error {
+ toolResultCalled = true
+ require.Equal(t, "echo", result.ToolName)
+ return nil
+ },
+ }
+
+ // Execute streaming agent
+ result, err := agent.Stream(ctx, streamCall)
+ require.NoError(t, err)
+
+ // Verify results
+ require.True(t, toolInputStartCalled, "OnToolInputStart should have been called")
+ require.True(t, toolInputDeltaCalled, "OnToolInputDelta should have been called")
+ require.True(t, toolInputEndCalled, "OnToolInputEnd should have been called")
+ require.True(t, toolCallCalled, "OnToolCall should have been called")
+ require.True(t, toolResultCalled, "OnToolResult should have been called")
+ require.Equal(t, 2, len(result.Steps)) // Two steps: tool call + final response
+
+ // Check that tool was executed in first step
+ firstStep := result.Steps[0]
+ toolCalls := firstStep.Content.ToolCalls()
+ require.Equal(t, 1, len(toolCalls))
+ require.Equal(t, "echo", toolCalls[0].ToolName)
+
+ toolResults := firstStep.Content.ToolResults()
+ require.Equal(t, 1, len(toolResults))
+ require.Equal(t, "echo", toolResults[0].ToolName)
+}
+
+// TestStreamingAgentTextDeltas tests text streaming (mirrors TS textStream tests)
+func TestStreamingAgentTextDeltas(t *testing.T) {
+ t.Parallel()
+
+ // Create a mock language model that returns text deltas
+ mockModel := &mockLanguageModel{
+ streamFunc: func(ctx context.Context, call Call) (StreamResponse, error) {
+ return func(yield func(StreamPart) bool) {
+ if !yield(StreamPart{Type: StreamPartTypeTextStart, ID: "text-1"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeTextDelta, ID: "text-1", Delta: "Hello"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeTextDelta, ID: "text-1", Delta: ", "}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeTextDelta, ID: "text-1", Delta: "world!"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeTextEnd, ID: "text-1"}) {
+ return
+ }
+ yield(StreamPart{
+ Type: StreamPartTypeFinish,
+ Usage: Usage{InputTokens: 3, OutputTokens: 10, TotalTokens: 13},
+ FinishReason: FinishReasonStop,
+ })
+ }, nil
+ },
+ }
+
+ agent := NewAgent(mockModel)
+ ctx := context.Background()
+
+ // Track text deltas
+ var textDeltas []string
+
+ streamCall := AgentStreamCall{
+ Prompt: "Say hello",
+ OnTextDelta: func(id, text string) error {
+ if text != "" {
+ textDeltas = append(textDeltas, text)
+ }
+ return nil
+ },
+ }
+
+ result, err := agent.Stream(ctx, streamCall)
+ require.NoError(t, err)
+
+ // Verify text deltas match expected pattern
+ require.Equal(t, []string{"Hello", ", ", "world!"}, textDeltas)
+ require.Equal(t, "Hello, world!", result.Response.Content.Text())
+ require.Equal(t, int64(13), result.TotalUsage.TotalTokens)
+}
+
+// TestStreamingAgentReasoning tests reasoning content (mirrors TS reasoning tests)
+func TestStreamingAgentReasoning(t *testing.T) {
+ t.Parallel()
+
+ mockModel := &mockLanguageModel{
+ streamFunc: func(ctx context.Context, call Call) (StreamResponse, error) {
+ return func(yield func(StreamPart) bool) {
+ if !yield(StreamPart{Type: StreamPartTypeReasoningStart, ID: "reasoning-1"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeReasoningDelta, ID: "reasoning-1", Delta: "I will open the conversation"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeReasoningDelta, ID: "reasoning-1", Delta: " with witty banter."}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeReasoningEnd, ID: "reasoning-1"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeTextStart, ID: "text-1"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeTextDelta, ID: "text-1", Delta: "Hi there!"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeTextEnd, ID: "text-1"}) {
+ return
+ }
+ yield(StreamPart{
+ Type: StreamPartTypeFinish,
+ Usage: Usage{InputTokens: 5, OutputTokens: 15, TotalTokens: 20},
+ FinishReason: FinishReasonStop,
+ })
+ }, nil
+ },
+ }
+
+ agent := NewAgent(mockModel)
+ ctx := context.Background()
+
+ var reasoningDeltas []string
+ var textDeltas []string
+
+ streamCall := AgentStreamCall{
+ Prompt: "Think and respond",
+ OnReasoningDelta: func(id, text string) error {
+ reasoningDeltas = append(reasoningDeltas, text)
+ return nil
+ },
+ OnTextDelta: func(id, text string) error {
+ textDeltas = append(textDeltas, text)
+ return nil
+ },
+ }
+
+ result, err := agent.Stream(ctx, streamCall)
+ require.NoError(t, err)
+
+ // Verify reasoning and text are separate
+ require.Equal(t, []string{"I will open the conversation", " with witty banter."}, reasoningDeltas)
+ require.Equal(t, []string{"Hi there!"}, textDeltas)
+ require.Equal(t, "Hi there!", result.Response.Content.Text())
+ require.Equal(t, "I will open the conversation with witty banter.", result.Response.Content.ReasoningText())
+}
+
+// TestStreamingAgentError tests error handling (mirrors TS error tests)
+func TestStreamingAgentError(t *testing.T) {
+ t.Parallel()
+
+ // Create a mock language model that returns an error
+ mockModel := &mockLanguageModel{
+ streamFunc: func(ctx context.Context, call Call) (StreamResponse, error) {
+ return func(yield func(StreamPart) bool) {
+ yield(StreamPart{Type: StreamPartTypeError, Error: fmt.Errorf("mock stream error")})
+ }, nil
+ },
+ }
+
+ agent := NewAgent(mockModel)
+ ctx := context.Background()
+
+ // Track error callbacks
+ var errorOccurred bool
+ var errorMessage string
+
+ streamCall := AgentStreamCall{
+ Prompt: "This will fail",
+
+ OnError: func(err error) {
+ errorOccurred = true
+ errorMessage = err.Error()
+ },
+ }
+
+ // Execute streaming agent
+ result, err := agent.Stream(ctx, streamCall)
+ require.Error(t, err)
+ require.Nil(t, result)
+ require.True(t, errorOccurred, "OnError should have been called")
+ require.Contains(t, errorMessage, "mock stream error")
+}
+
+// TestStreamingAgentSources tests source handling (mirrors TS source tests)
+func TestStreamingAgentSources(t *testing.T) {
+ t.Parallel()
+
+ mockModel := &mockLanguageModel{
+ streamFunc: func(ctx context.Context, call Call) (StreamResponse, error) {
+ return func(yield func(StreamPart) bool) {
+ if !yield(StreamPart{
+ Type: StreamPartTypeSource,
+ ID: "source-1",
+ SourceType: SourceTypeURL,
+ URL: "https://example.com",
+ Title: "Example",
+ }) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeTextStart, ID: "text-1"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeTextDelta, ID: "text-1", Delta: "Hello!"}) {
+ return
+ }
+ if !yield(StreamPart{Type: StreamPartTypeTextEnd, ID: "text-1"}) {
+ return
+ }
+ if !yield(StreamPart{
+ Type: StreamPartTypeSource,
+ ID: "source-2",
+ SourceType: SourceTypeDocument,
+ Title: "Document Example",
+ }) {
+ return
+ }
+ yield(StreamPart{
+ Type: StreamPartTypeFinish,
+ Usage: Usage{InputTokens: 3, OutputTokens: 5, TotalTokens: 8},
+ FinishReason: FinishReasonStop,
+ })
+ }, nil
+ },
+ }
+
+ agent := NewAgent(mockModel)
+ ctx := context.Background()
+
+ var sources []SourceContent
+
+ streamCall := AgentStreamCall{
+ Prompt: "Search and respond",
+ OnSource: func(source SourceContent) error {
+ sources = append(sources, source)
+ return nil
+ },
+ }
+
+ result, err := agent.Stream(ctx, streamCall)
+ require.NoError(t, err)
+
+ // Verify sources were captured
+ require.Equal(t, 2, len(sources))
+ require.Equal(t, SourceTypeURL, sources[0].SourceType)
+ require.Equal(t, "https://example.com", sources[0].URL)
+ require.Equal(t, "Example", sources[0].Title)
+ require.Equal(t, SourceTypeDocument, sources[1].SourceType)
+ require.Equal(t, "Document Example", sources[1].Title)
+
+ // Verify sources are in final result
+ resultSources := result.Response.Content.Sources()
+ require.Equal(t, 2, len(resultSources))
+}
diff --git a/internal/fantasy/agent_test.go b/internal/fantasy/agent_test.go
new file mode 100644
index 000000000..33c137a13
--- /dev/null
+++ b/internal/fantasy/agent_test.go
@@ -0,0 +1,1770 @@
+package fantasy
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+// Mock tool for testing
+type mockTool struct {
+ name string
+ providerOptions ProviderOptions
+ description string
+ parameters map[string]any
+ required []string
+ executeFunc func(ctx context.Context, call ToolCall) (ToolResponse, error)
+}
+
+func (m *mockTool) SetProviderOptions(opts ProviderOptions) {
+ m.providerOptions = opts
+}
+
+func (m *mockTool) ProviderOptions() ProviderOptions {
+ return m.providerOptions
+}
+
+func (m *mockTool) Info() ToolInfo {
+ return ToolInfo{
+ Name: m.name,
+ Description: m.description,
+ Parameters: m.parameters,
+ Required: m.required,
+ }
+}
+
+func (m *mockTool) Run(ctx context.Context, call ToolCall) (ToolResponse, error) {
+ if m.executeFunc != nil {
+ return m.executeFunc(ctx, call)
+ }
+ return ToolResponse{Content: "mock result", IsError: false}, nil
+}
+
+// Mock language model for testing
+type mockLanguageModel struct {
+ generateFunc func(ctx context.Context, call Call) (*Response, error)
+ streamFunc func(ctx context.Context, call Call) (StreamResponse, error)
+}
+
+func (m *mockLanguageModel) Generate(ctx context.Context, call Call) (*Response, error) {
+ if m.generateFunc != nil {
+ return m.generateFunc(ctx, call)
+ }
+ return &Response{
+ Content: []Content{
+ TextContent{Text: "Hello, world!"},
+ },
+ Usage: Usage{
+ InputTokens: 3,
+ OutputTokens: 10,
+ TotalTokens: 13,
+ },
+ FinishReason: FinishReasonStop,
+ }, nil
+}
+
+func (m *mockLanguageModel) Stream(ctx context.Context, call Call) (StreamResponse, error) {
+ if m.streamFunc != nil {
+ return m.streamFunc(ctx, call)
+ }
+ return nil, fmt.Errorf("mock stream not implemented")
+}
+
+func (m *mockLanguageModel) Provider() string {
+ return "mock-provider"
+}
+
+func (m *mockLanguageModel) Model() string {
+ return "mock-model"
+}
+
+func (m *mockLanguageModel) GenerateObject(ctx context.Context, call ObjectCall) (*ObjectResponse, error) {
+ return nil, fmt.Errorf("mock GenerateObject not implemented")
+}
+
+func (m *mockLanguageModel) StreamObject(ctx context.Context, call ObjectCall) (ObjectStreamResponse, error) {
+ return nil, fmt.Errorf("mock StreamObject not implemented")
+}
+
+// Test result.content - comprehensive content types (matches TS test)
+func TestAgent_Generate_ResultContent_AllTypes(t *testing.T) {
+ t.Parallel()
+
+ // Create a type-safe tool using the new API
+ type TestInput struct {
+ Value string `json:"value" description:"Test value"`
+ }
+
+ tool1 := NewAgentTool(
+ "tool1",
+ "Test tool",
+ func(ctx context.Context, input TestInput, _ ToolCall) (ToolResponse, error) {
+ require.Equal(t, "value", input.Value)
+ return ToolResponse{Content: "result1", IsError: false}, nil
+ },
+ )
+
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ return &Response{
+ Content: []Content{
+ TextContent{Text: "Hello, world!"},
+ SourceContent{
+ ID: "123",
+ URL: "https://example.com",
+ Title: "Example",
+ SourceType: SourceTypeURL,
+ },
+ FileContent{
+ Data: []byte{1, 2, 3},
+ MediaType: "image/png",
+ },
+ ReasoningContent{
+ Text: "I will open the conversation with witty banter.",
+ },
+ ToolCallContent{
+ ToolCallID: "call-1",
+ ToolName: "tool1",
+ Input: `{"value":"value"}`,
+ },
+ TextContent{Text: "More text"},
+ },
+ Usage: Usage{
+ InputTokens: 3,
+ OutputTokens: 10,
+ TotalTokens: 13,
+ },
+ FinishReason: FinishReasonStop, // Note: FinishReasonStop, not ToolCalls
+ }, nil
+ },
+ }
+
+ agent := NewAgent(model, WithTools(tool1))
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "prompt",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Len(t, result.Steps, 1) // Single step like TypeScript
+
+ // Check final response content includes tool result
+ require.Len(t, result.Response.Content, 7) // original 6 + 1 tool result
+
+ // Verify each content type in order
+ textContent, ok := AsContentType[TextContent](result.Response.Content[0])
+ require.True(t, ok)
+ require.Equal(t, "Hello, world!", textContent.Text)
+
+ sourceContent, ok := AsContentType[SourceContent](result.Response.Content[1])
+ require.True(t, ok)
+ require.Equal(t, "123", sourceContent.ID)
+
+ fileContent, ok := AsContentType[FileContent](result.Response.Content[2])
+ require.True(t, ok)
+ require.Equal(t, []byte{1, 2, 3}, fileContent.Data)
+
+ reasoningContent, ok := AsContentType[ReasoningContent](result.Response.Content[3])
+ require.True(t, ok)
+ require.Equal(t, "I will open the conversation with witty banter.", reasoningContent.Text)
+
+ toolCallContent, ok := AsContentType[ToolCallContent](result.Response.Content[4])
+ require.True(t, ok)
+ require.Equal(t, "call-1", toolCallContent.ToolCallID)
+
+ moreTextContent, ok := AsContentType[TextContent](result.Response.Content[5])
+ require.True(t, ok)
+ require.Equal(t, "More text", moreTextContent.Text)
+
+ // Tool result should be appended
+ toolResultContent, ok := AsContentType[ToolResultContent](result.Response.Content[6])
+ require.True(t, ok)
+ require.Equal(t, "call-1", toolResultContent.ToolCallID)
+ require.Equal(t, "tool1", toolResultContent.ToolName)
+}
+
+// Test result.text extraction
+func TestAgent_Generate_ResultText(t *testing.T) {
+ t.Parallel()
+
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ return &Response{
+ Content: []Content{
+ TextContent{Text: "Hello, world!"},
+ },
+ Usage: Usage{
+ InputTokens: 3,
+ OutputTokens: 10,
+ TotalTokens: 13,
+ },
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ agent := NewAgent(model)
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "prompt",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+
+ // Test text extraction from content
+ text := result.Response.Content.Text()
+ require.Equal(t, "Hello, world!", text)
+}
+
+// Test result.toolCalls extraction (matches TS test exactly)
+func TestAgent_Generate_ResultToolCalls(t *testing.T) {
+ t.Parallel()
+
+ // Create type-safe tools using the new API
+ type Tool1Input struct {
+ Value string `json:"value" description:"Test value"`
+ }
+
+ type Tool2Input struct {
+ SomethingElse string `json:"somethingElse" description:"Another test value"`
+ }
+
+ tool1 := NewAgentTool(
+ "tool1",
+ "Test tool 1",
+ func(ctx context.Context, input Tool1Input, _ ToolCall) (ToolResponse, error) {
+ return ToolResponse{Content: "result1", IsError: false}, nil
+ },
+ )
+
+ tool2 := NewAgentTool(
+ "tool2",
+ "Test tool 2",
+ func(ctx context.Context, input Tool2Input, _ ToolCall) (ToolResponse, error) {
+ return ToolResponse{Content: "result2", IsError: false}, nil
+ },
+ )
+
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ // Verify tools are passed correctly
+ require.Len(t, call.Tools, 2)
+ require.Equal(t, ToolChoiceAuto, *call.ToolChoice) // Should be auto, not required
+
+ // Verify prompt structure
+ require.Len(t, call.Prompt, 1)
+ require.Equal(t, MessageRoleUser, call.Prompt[0].Role)
+
+ return &Response{
+ Content: []Content{
+ ToolCallContent{
+ ToolCallID: "call-1",
+ ToolName: "tool1",
+ Input: `{"value":"value"}`,
+ },
+ },
+ Usage: Usage{
+ InputTokens: 3,
+ OutputTokens: 10,
+ TotalTokens: 13,
+ },
+ FinishReason: FinishReasonStop, // Note: Stop, not ToolCalls
+ }, nil
+ },
+ }
+
+ agent := NewAgent(model, WithTools(tool1, tool2))
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test-input",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Len(t, result.Steps, 1) // Single step
+
+ // Extract tool calls from final response (should be empty since tools don't execute)
+ var toolCalls []ToolCallContent
+ for _, content := range result.Response.Content {
+ if toolCall, ok := AsContentType[ToolCallContent](content); ok {
+ toolCalls = append(toolCalls, toolCall)
+ }
+ }
+
+ require.Len(t, toolCalls, 1)
+ require.Equal(t, "call-1", toolCalls[0].ToolCallID)
+ require.Equal(t, "tool1", toolCalls[0].ToolName)
+
+ // Parse and verify input
+ var input map[string]any
+ err = json.Unmarshal([]byte(toolCalls[0].Input), &input)
+ require.NoError(t, err)
+ require.Equal(t, "value", input["value"])
+}
+
+// Test result.toolResults extraction (matches TS test exactly)
+func TestAgent_Generate_ResultToolResults(t *testing.T) {
+ t.Parallel()
+
+ // Create type-safe tool using the new API
+ type TestInput struct {
+ Value string `json:"value" description:"Test value"`
+ }
+
+ tool1 := NewAgentTool(
+ "tool1",
+ "Test tool",
+ func(ctx context.Context, input TestInput, _ ToolCall) (ToolResponse, error) {
+ require.Equal(t, "value", input.Value)
+ return ToolResponse{Content: "result1", IsError: false}, nil
+ },
+ )
+
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ // Verify tools and tool choice
+ require.Len(t, call.Tools, 1)
+ require.Equal(t, ToolChoiceAuto, *call.ToolChoice)
+
+ // Verify prompt
+ require.Len(t, call.Prompt, 1)
+ require.Equal(t, MessageRoleUser, call.Prompt[0].Role)
+
+ return &Response{
+ Content: []Content{
+ ToolCallContent{
+ ToolCallID: "call-1",
+ ToolName: "tool1",
+ Input: `{"value":"value"}`,
+ },
+ },
+ Usage: Usage{
+ InputTokens: 3,
+ OutputTokens: 10,
+ TotalTokens: 13,
+ },
+ FinishReason: FinishReasonStop, // Note: Stop, not ToolCalls
+ }, nil
+ },
+ }
+
+ agent := NewAgent(model, WithTools(tool1))
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test-input",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Len(t, result.Steps, 1) // Single step
+
+ // Extract tool results from final response
+ var toolResults []ToolResultContent
+ for _, content := range result.Response.Content {
+ if toolResult, ok := AsContentType[ToolResultContent](content); ok {
+ toolResults = append(toolResults, toolResult)
+ }
+ }
+
+ require.Len(t, toolResults, 1)
+ require.Equal(t, "call-1", toolResults[0].ToolCallID)
+ require.Equal(t, "tool1", toolResults[0].ToolName)
+
+ // Verify result content
+ textResult, ok := toolResults[0].Result.(ToolResultOutputContentText)
+ require.True(t, ok)
+ require.Equal(t, "result1", textResult.Text)
+}
+
+// Test multi-step scenario (matches TS "2 steps: initial, tool-result" test)
+func TestAgent_Generate_MultipleSteps(t *testing.T) {
+ t.Parallel()
+
+ // Create type-safe tool using the new API
+ type TestInput struct {
+ Value string `json:"value" description:"Test value"`
+ }
+
+ tool1 := NewAgentTool(
+ "tool1",
+ "Test tool",
+ func(ctx context.Context, input TestInput, _ ToolCall) (ToolResponse, error) {
+ require.Equal(t, "value", input.Value)
+ return ToolResponse{Content: "result1", IsError: false}, nil
+ },
+ )
+
+ callCount := 0
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ callCount++
+ switch callCount {
+ case 1:
+ // First call - return tool call with FinishReasonToolCalls
+ return &Response{
+ Content: []Content{
+ ToolCallContent{
+ ToolCallID: "call-1",
+ ToolName: "tool1",
+ Input: `{"value":"value"}`,
+ },
+ },
+ Usage: Usage{
+ InputTokens: 10,
+ OutputTokens: 5,
+ TotalTokens: 15,
+ },
+ FinishReason: FinishReasonToolCalls, // This triggers multi-step
+ }, nil
+ case 2:
+ // Second call - return final text
+ return &Response{
+ Content: []Content{
+ TextContent{Text: "Hello, world!"},
+ },
+ Usage: Usage{
+ InputTokens: 3,
+ OutputTokens: 10,
+ TotalTokens: 13,
+ },
+ FinishReason: FinishReasonStop,
+ }, nil
+ default:
+ t.Fatalf("Unexpected call count: %d", callCount)
+ return nil, nil
+ }
+ },
+ }
+
+ agent := NewAgent(model, WithTools(tool1))
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test-input",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Len(t, result.Steps, 2)
+
+ // Check total usage sums both steps
+ require.Equal(t, int64(13), result.TotalUsage.InputTokens) // 10 + 3
+ require.Equal(t, int64(15), result.TotalUsage.OutputTokens) // 5 + 10
+ require.Equal(t, int64(28), result.TotalUsage.TotalTokens) // 15 + 13
+
+ // Final response should be from last step
+ require.Len(t, result.Response.Content, 1)
+ textContent, ok := AsContentType[TextContent](result.Response.Content[0])
+ require.True(t, ok)
+ require.Equal(t, "Hello, world!", textContent.Text)
+
+ // result.toolCalls should be empty (from last step)
+ var toolCalls []ToolCallContent
+ for _, content := range result.Response.Content {
+ if _, ok := AsContentType[ToolCallContent](content); ok {
+ toolCalls = append(toolCalls, content.(ToolCallContent))
+ }
+ }
+ require.Len(t, toolCalls, 0)
+
+ // result.toolResults should be empty (from last step)
+ var toolResults []ToolResultContent
+ for _, content := range result.Response.Content {
+ if _, ok := AsContentType[ToolResultContent](content); ok {
+ toolResults = append(toolResults, content.(ToolResultContent))
+ }
+ }
+ require.Len(t, toolResults, 0)
+}
+
+// Test basic text generation
+func TestAgent_Generate_BasicText(t *testing.T) {
+ t.Parallel()
+
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ return &Response{
+ Content: []Content{
+ TextContent{Text: "Hello, world!"},
+ },
+ Usage: Usage{
+ InputTokens: 3,
+ OutputTokens: 10,
+ TotalTokens: 13,
+ },
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ agent := NewAgent(model)
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Len(t, result.Steps, 1)
+
+ // Check final response
+ require.Len(t, result.Response.Content, 1)
+ textContent, ok := AsContentType[TextContent](result.Response.Content[0])
+ require.True(t, ok)
+ require.Equal(t, "Hello, world!", textContent.Text)
+
+ // Check usage
+ require.Equal(t, int64(3), result.Response.Usage.InputTokens)
+ require.Equal(t, int64(10), result.Response.Usage.OutputTokens)
+ require.Equal(t, int64(13), result.Response.Usage.TotalTokens)
+
+ // Check total usage
+ require.Equal(t, int64(3), result.TotalUsage.InputTokens)
+ require.Equal(t, int64(10), result.TotalUsage.OutputTokens)
+ require.Equal(t, int64(13), result.TotalUsage.TotalTokens)
+}
+
+// Test empty prompt error
+func TestAgent_Generate_EmptyPrompt(t *testing.T) {
+ t.Parallel()
+
+ model := &mockLanguageModel{}
+ agent := NewAgent(model)
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "", // Empty prompt should cause error
+ })
+
+ require.Error(t, err)
+ require.Nil(t, result)
+ require.Contains(t, err.Error(), "invalid argument: prompt can't be empty")
+}
+
+// Test with system prompt
+func TestAgent_Generate_WithSystemPrompt(t *testing.T) {
+ t.Parallel()
+
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ // Verify system message is included
+ require.Len(t, call.Prompt, 2) // system + user
+ require.Equal(t, MessageRoleSystem, call.Prompt[0].Role)
+ require.Equal(t, MessageRoleUser, call.Prompt[1].Role)
+
+ systemPart, ok := call.Prompt[0].Content[0].(TextPart)
+ require.True(t, ok)
+ require.Equal(t, "You are a helpful assistant", systemPart.Text)
+
+ return &Response{
+ Content: []Content{
+ TextContent{Text: "Hello, world!"},
+ },
+ Usage: Usage{
+ InputTokens: 3,
+ OutputTokens: 10,
+ TotalTokens: 13,
+ },
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ agent := NewAgent(model, WithSystemPrompt("You are a helpful assistant"))
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+}
+
+// Test options.activeTools filtering
+func TestAgent_Generate_OptionsActiveTools(t *testing.T) {
+ t.Parallel()
+
+ tool1 := &mockTool{
+ name: "tool1",
+ description: "Test tool 1",
+ parameters: map[string]any{
+ "value": map[string]any{"type": "string"},
+ },
+ required: []string{"value"},
+ }
+
+ tool2 := &mockTool{
+ name: "tool2",
+ description: "Test tool 2",
+ parameters: map[string]any{
+ "value": map[string]any{"type": "string"},
+ },
+ required: []string{"value"},
+ }
+
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ // Verify only tool1 is available
+ require.Len(t, call.Tools, 1)
+ functionTool, ok := call.Tools[0].(FunctionTool)
+ require.True(t, ok)
+ require.Equal(t, "tool1", functionTool.Name)
+
+ return &Response{
+ Content: []Content{
+ TextContent{Text: "Hello, world!"},
+ },
+ Usage: Usage{
+ InputTokens: 3,
+ OutputTokens: 10,
+ TotalTokens: 13,
+ },
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ agent := NewAgent(model, WithTools(tool1, tool2))
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test-input",
+ ActiveTools: []string{"tool1"}, // Only tool1 should be active
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+}
+
+func TestResponseContent_Getters(t *testing.T) {
+ t.Parallel()
+
+ // Create test content with all types
+ content := ResponseContent{
+ TextContent{Text: "Hello world"},
+ ReasoningContent{Text: "Let me think..."},
+ FileContent{Data: []byte("file data"), MediaType: "text/plain"},
+ SourceContent{SourceType: SourceTypeURL, URL: "https://example.com", Title: "Example"},
+ ToolCallContent{ToolCallID: "call1", ToolName: "test_tool", Input: `{"arg": "value"}`},
+ ToolResultContent{ToolCallID: "call1", ToolName: "test_tool", Result: ToolResultOutputContentText{Text: "result"}},
+ }
+
+ // Test Text()
+ require.Equal(t, "Hello world", content.Text())
+
+ // Test Reasoning()
+ reasoning := content.Reasoning()
+ require.Len(t, reasoning, 1)
+ require.Equal(t, "Let me think...", reasoning[0].Text)
+
+ // Test ReasoningText()
+ require.Equal(t, "Let me think...", content.ReasoningText())
+
+ // Test Files()
+ files := content.Files()
+ require.Len(t, files, 1)
+ require.Equal(t, "text/plain", files[0].MediaType)
+ require.Equal(t, []byte("file data"), files[0].Data)
+
+ // Test Sources()
+ sources := content.Sources()
+ require.Len(t, sources, 1)
+ require.Equal(t, SourceTypeURL, sources[0].SourceType)
+ require.Equal(t, "https://example.com", sources[0].URL)
+ require.Equal(t, "Example", sources[0].Title)
+
+ // Test ToolCalls()
+ toolCalls := content.ToolCalls()
+ require.Len(t, toolCalls, 1)
+ require.Equal(t, "call1", toolCalls[0].ToolCallID)
+ require.Equal(t, "test_tool", toolCalls[0].ToolName)
+ require.Equal(t, `{"arg": "value"}`, toolCalls[0].Input)
+
+ // Test ToolResults()
+ toolResults := content.ToolResults()
+ require.Len(t, toolResults, 1)
+ require.Equal(t, "call1", toolResults[0].ToolCallID)
+ require.Equal(t, "test_tool", toolResults[0].ToolName)
+ result, ok := AsToolResultOutputType[ToolResultOutputContentText](toolResults[0].Result)
+ require.True(t, ok)
+ require.Equal(t, "result", result.Text)
+}
+
+func TestResponseContent_Getters_Empty(t *testing.T) {
+ t.Parallel()
+
+ // Test with empty content
+ content := ResponseContent{}
+
+ require.Equal(t, "", content.Text())
+ require.Equal(t, "", content.ReasoningText())
+ require.Empty(t, content.Reasoning())
+ require.Empty(t, content.Files())
+ require.Empty(t, content.Sources())
+ require.Empty(t, content.ToolCalls())
+ require.Empty(t, content.ToolResults())
+}
+
+func TestResponseContent_Getters_MultipleItems(t *testing.T) {
+ t.Parallel()
+
+ // Test with multiple items of same type
+ content := ResponseContent{
+ ReasoningContent{Text: "First thought"},
+ ReasoningContent{Text: "Second thought"},
+ FileContent{Data: []byte("file1"), MediaType: "text/plain"},
+ FileContent{Data: []byte("file2"), MediaType: "image/png"},
+ }
+
+ // Test multiple reasoning
+ reasoning := content.Reasoning()
+ require.Len(t, reasoning, 2)
+ require.Equal(t, "First thought", reasoning[0].Text)
+ require.Equal(t, "Second thought", reasoning[1].Text)
+
+ // Test concatenated reasoning text
+ require.Equal(t, "First thoughtSecond thought", content.ReasoningText())
+
+ // Test multiple files
+ files := content.Files()
+ require.Len(t, files, 2)
+ require.Equal(t, "text/plain", files[0].MediaType)
+ require.Equal(t, "image/png", files[1].MediaType)
+}
+
+func TestStopConditions(t *testing.T) {
+ t.Parallel()
+
+ // Create test steps
+ step1 := StepResult{
+ Response: Response{
+ Content: ResponseContent{
+ TextContent{Text: "Hello"},
+ },
+ FinishReason: FinishReasonToolCalls,
+ Usage: Usage{TotalTokens: 10},
+ },
+ }
+
+ step2 := StepResult{
+ Response: Response{
+ Content: ResponseContent{
+ TextContent{Text: "World"},
+ ToolCallContent{ToolCallID: "call1", ToolName: "search", Input: `{"query": "test"}`},
+ },
+ FinishReason: FinishReasonStop,
+ Usage: Usage{TotalTokens: 15},
+ },
+ }
+
+ step3 := StepResult{
+ Response: Response{
+ Content: ResponseContent{
+ ReasoningContent{Text: "Let me think..."},
+ FileContent{Data: []byte("data"), MediaType: "text/plain"},
+ },
+ FinishReason: FinishReasonLength,
+ Usage: Usage{TotalTokens: 20},
+ },
+ }
+
+ t.Run("StepCountIs", func(t *testing.T) {
+ t.Parallel()
+ condition := StepCountIs(2)
+
+ // Should not stop with 1 step
+ require.False(t, condition([]StepResult{step1}))
+
+ // Should stop with 2 steps
+ require.True(t, condition([]StepResult{step1, step2}))
+
+ // Should stop with more than 2 steps
+ require.True(t, condition([]StepResult{step1, step2, step3}))
+
+ // Should not stop with empty steps
+ require.False(t, condition([]StepResult{}))
+ })
+
+ t.Run("HasToolCall", func(t *testing.T) {
+ t.Parallel()
+ condition := HasToolCall("search")
+
+ // Should not stop when tool not called
+ require.False(t, condition([]StepResult{step1}))
+
+ // Should stop when tool is called in last step
+ require.True(t, condition([]StepResult{step1, step2}))
+
+ // Should not stop when tool called in earlier step but not last
+ require.False(t, condition([]StepResult{step1, step2, step3}))
+
+ // Should not stop with empty steps
+ require.False(t, condition([]StepResult{}))
+
+ // Should not stop when different tool is called
+ differentToolCondition := HasToolCall("different_tool")
+ require.False(t, differentToolCondition([]StepResult{step1, step2}))
+ })
+
+ t.Run("HasContent", func(t *testing.T) {
+ t.Parallel()
+ reasoningCondition := HasContent(ContentTypeReasoning)
+ fileCondition := HasContent(ContentTypeFile)
+
+ // Should not stop when content type not present
+ require.False(t, reasoningCondition([]StepResult{step1, step2}))
+
+ // Should stop when content type is present in last step
+ require.True(t, reasoningCondition([]StepResult{step1, step2, step3}))
+ require.True(t, fileCondition([]StepResult{step1, step2, step3}))
+
+ // Should not stop with empty steps
+ require.False(t, reasoningCondition([]StepResult{}))
+ })
+
+ t.Run("FinishReasonIs", func(t *testing.T) {
+ t.Parallel()
+ stopCondition := FinishReasonIs(FinishReasonStop)
+ lengthCondition := FinishReasonIs(FinishReasonLength)
+
+ // Should not stop when finish reason doesn't match
+ require.False(t, stopCondition([]StepResult{step1}))
+
+ // Should stop when finish reason matches in last step
+ require.True(t, stopCondition([]StepResult{step1, step2}))
+ require.True(t, lengthCondition([]StepResult{step1, step2, step3}))
+
+ // Should not stop with empty steps
+ require.False(t, stopCondition([]StepResult{}))
+ })
+
+ t.Run("MaxTokensUsed", func(t *testing.T) {
+ condition := MaxTokensUsed(30)
+
+ // Should not stop when under limit
+ require.False(t, condition([]StepResult{step1})) // 10 tokens
+ require.False(t, condition([]StepResult{step1, step2})) // 25 tokens
+
+ // Should stop when at or over limit
+ require.True(t, condition([]StepResult{step1, step2, step3})) // 45 tokens
+
+ // Should not stop with empty steps
+ require.False(t, condition([]StepResult{}))
+ })
+}
+
+func TestStopConditions_Integration(t *testing.T) {
+ t.Parallel()
+
+ t.Run("StepCountIs integration", func(t *testing.T) {
+ t.Parallel()
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ return &Response{
+ Content: ResponseContent{
+ TextContent{Text: "Mock response"},
+ },
+ Usage: Usage{
+ InputTokens: 3,
+ OutputTokens: 10,
+ TotalTokens: 13,
+ },
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ agent := NewAgent(model, WithStopConditions(StepCountIs(1)))
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Len(t, result.Steps, 1) // Should stop after 1 step
+ })
+
+ t.Run("Multiple stop conditions", func(t *testing.T) {
+ t.Parallel()
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ return &Response{
+ Content: ResponseContent{
+ TextContent{Text: "Mock response"},
+ },
+ Usage: Usage{
+ InputTokens: 3,
+ OutputTokens: 10,
+ TotalTokens: 13,
+ },
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ agent := NewAgent(model, WithStopConditions(
+ StepCountIs(5), // Stop after 5 steps
+ FinishReasonIs(FinishReasonStop), // Or stop on finish reason
+ ))
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ // Should stop on first condition met (finish reason stop)
+ require.Equal(t, FinishReasonStop, result.Response.FinishReason)
+ })
+}
+
+func TestPrepareStep(t *testing.T) {
+ t.Parallel()
+
+ t.Run("System prompt modification", func(t *testing.T) {
+ t.Parallel()
+ var capturedSystemPrompt string
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ // Capture the system message to verify it was modified
+ if len(call.Prompt) > 0 && call.Prompt[0].Role == MessageRoleSystem {
+ if len(call.Prompt[0].Content) > 0 {
+ if textPart, ok := AsContentType[TextPart](call.Prompt[0].Content[0]); ok {
+ capturedSystemPrompt = textPart.Text
+ }
+ }
+ }
+ return &Response{
+ Content: ResponseContent{
+ TextContent{Text: "Response"},
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ prepareStepFunc := func(ctx context.Context, options PrepareStepFunctionOptions) (context.Context, PrepareStepResult, error) {
+ newSystem := "Modified system prompt for step " + fmt.Sprintf("%d", options.StepNumber)
+ return ctx, PrepareStepResult{
+ Model: options.Model,
+ Messages: options.Messages,
+ System: &newSystem,
+ }, nil
+ }
+
+ agent := NewAgent(model, WithSystemPrompt("Original system prompt"))
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ PrepareStep: prepareStepFunc,
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Equal(t, "Modified system prompt for step 0", capturedSystemPrompt)
+ })
+
+ t.Run("Tool choice modification", func(t *testing.T) {
+ t.Parallel()
+ var capturedToolChoice *ToolChoice
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ capturedToolChoice = call.ToolChoice
+ return &Response{
+ Content: ResponseContent{
+ TextContent{Text: "Response"},
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ prepareStepFunc := func(ctx context.Context, options PrepareStepFunctionOptions) (context.Context, PrepareStepResult, error) {
+ toolChoice := ToolChoiceNone
+ return ctx, PrepareStepResult{
+ Model: options.Model,
+ Messages: options.Messages,
+ ToolChoice: &toolChoice,
+ }, nil
+ }
+
+ agent := NewAgent(model)
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ PrepareStep: prepareStepFunc,
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.NotNil(t, capturedToolChoice)
+ require.Equal(t, ToolChoiceNone, *capturedToolChoice)
+ })
+
+ t.Run("Active tools modification", func(t *testing.T) {
+ t.Parallel()
+ var capturedToolNames []string
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ // Capture tool names to verify active tools were modified
+ for _, tool := range call.Tools {
+ capturedToolNames = append(capturedToolNames, tool.GetName())
+ }
+ return &Response{
+ Content: ResponseContent{
+ TextContent{Text: "Response"},
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ tool1 := &mockTool{name: "tool1", description: "Tool 1"}
+ tool2 := &mockTool{name: "tool2", description: "Tool 2"}
+ tool3 := &mockTool{name: "tool3", description: "Tool 3"}
+
+ prepareStepFunc := func(ctx context.Context, options PrepareStepFunctionOptions) (context.Context, PrepareStepResult, error) {
+ activeTools := []string{"tool2"} // Only tool2 should be active
+ return ctx, PrepareStepResult{
+ Model: options.Model,
+ Messages: options.Messages,
+ ActiveTools: activeTools,
+ }, nil
+ }
+
+ agent := NewAgent(model, WithTools(tool1, tool2, tool3))
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ PrepareStep: prepareStepFunc,
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Len(t, capturedToolNames, 1)
+ require.Equal(t, "tool2", capturedToolNames[0])
+ })
+
+ t.Run("No tools when DisableAllTools is true", func(t *testing.T) {
+ t.Parallel()
+ var capturedToolCount int
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ capturedToolCount = len(call.Tools)
+ return &Response{
+ Content: ResponseContent{
+ TextContent{Text: "Response"},
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ tool1 := &mockTool{name: "tool1", description: "Tool 1"}
+
+ prepareStepFunc := func(ctx context.Context, options PrepareStepFunctionOptions) (context.Context, PrepareStepResult, error) {
+ return ctx, PrepareStepResult{
+ Model: options.Model,
+ Messages: options.Messages,
+ DisableAllTools: true, // Disable all tools for this step
+ }, nil
+ }
+
+ agent := NewAgent(model, WithTools(tool1))
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ PrepareStep: prepareStepFunc,
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Equal(t, 0, capturedToolCount) // No tools should be passed
+ })
+
+ t.Run("All fields modified together", func(t *testing.T) {
+ t.Parallel()
+ var capturedSystemPrompt string
+ var capturedToolChoice *ToolChoice
+ var capturedToolNames []string
+
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ // Capture system prompt
+ if len(call.Prompt) > 0 && call.Prompt[0].Role == MessageRoleSystem {
+ if len(call.Prompt[0].Content) > 0 {
+ if textPart, ok := AsContentType[TextPart](call.Prompt[0].Content[0]); ok {
+ capturedSystemPrompt = textPart.Text
+ }
+ }
+ }
+ // Capture tool choice
+ capturedToolChoice = call.ToolChoice
+ // Capture tool names
+ for _, tool := range call.Tools {
+ capturedToolNames = append(capturedToolNames, tool.GetName())
+ }
+ return &Response{
+ Content: ResponseContent{
+ TextContent{Text: "Response"},
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ tool1 := &mockTool{name: "tool1", description: "Tool 1"}
+ tool2 := &mockTool{name: "tool2", description: "Tool 2"}
+
+ prepareStepFunc := func(ctx context.Context, options PrepareStepFunctionOptions) (context.Context, PrepareStepResult, error) {
+ newSystem := "Step-specific system"
+ toolChoice := SpecificToolChoice("tool1")
+ activeTools := []string{"tool1"}
+ return ctx, PrepareStepResult{
+ Model: options.Model,
+ Messages: options.Messages,
+ System: &newSystem,
+ ToolChoice: &toolChoice,
+ ActiveTools: activeTools,
+ }, nil
+ }
+
+ agent := NewAgent(model, WithSystemPrompt("Original system"), WithTools(tool1, tool2))
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ PrepareStep: prepareStepFunc,
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Equal(t, "Step-specific system", capturedSystemPrompt)
+ require.NotNil(t, capturedToolChoice)
+ require.Equal(t, SpecificToolChoice("tool1"), *capturedToolChoice)
+ require.Len(t, capturedToolNames, 1)
+ require.Equal(t, "tool1", capturedToolNames[0])
+ })
+
+ t.Run("Nil fields use parent values", func(t *testing.T) {
+ t.Parallel()
+ var capturedSystemPrompt string
+ var capturedToolChoice *ToolChoice
+ var capturedToolNames []string
+
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ // Capture system prompt
+ if len(call.Prompt) > 0 && call.Prompt[0].Role == MessageRoleSystem {
+ if len(call.Prompt[0].Content) > 0 {
+ if textPart, ok := AsContentType[TextPart](call.Prompt[0].Content[0]); ok {
+ capturedSystemPrompt = textPart.Text
+ }
+ }
+ }
+ // Capture tool choice
+ capturedToolChoice = call.ToolChoice
+ // Capture tool names
+ for _, tool := range call.Tools {
+ capturedToolNames = append(capturedToolNames, tool.GetName())
+ }
+ return &Response{
+ Content: ResponseContent{
+ TextContent{Text: "Response"},
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ tool1 := &mockTool{name: "tool1", description: "Tool 1"}
+
+ prepareStepFunc := func(ctx context.Context, options PrepareStepFunctionOptions) (context.Context, PrepareStepResult, error) {
+ // All optional fields are nil, should use parent values
+ return ctx, PrepareStepResult{
+ Model: options.Model,
+ Messages: options.Messages,
+ System: nil, // Use parent
+ ToolChoice: nil, // Use parent (auto)
+ ActiveTools: nil, // Use parent (all tools)
+ }, nil
+ }
+
+ agent := NewAgent(model, WithSystemPrompt("Parent system"), WithTools(tool1))
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ PrepareStep: prepareStepFunc,
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Equal(t, "Parent system", capturedSystemPrompt)
+ require.NotNil(t, capturedToolChoice)
+ require.Equal(t, ToolChoiceAuto, *capturedToolChoice) // Default
+ require.Len(t, capturedToolNames, 1)
+ require.Equal(t, "tool1", capturedToolNames[0])
+ })
+
+ t.Run("Empty ActiveTools means all tools", func(t *testing.T) {
+ t.Parallel()
+ var capturedToolNames []string
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ // Capture tool names to verify all tools are included
+ for _, tool := range call.Tools {
+ capturedToolNames = append(capturedToolNames, tool.GetName())
+ }
+ return &Response{
+ Content: ResponseContent{
+ TextContent{Text: "Response"},
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ tool1 := &mockTool{name: "tool1", description: "Tool 1"}
+ tool2 := &mockTool{name: "tool2", description: "Tool 2"}
+
+ prepareStepFunc := func(ctx context.Context, options PrepareStepFunctionOptions) (context.Context, PrepareStepResult, error) {
+ return ctx, PrepareStepResult{
+ Model: options.Model,
+ Messages: options.Messages,
+ ActiveTools: []string{}, // Empty slice means all tools
+ }, nil
+ }
+
+ agent := NewAgent(model, WithTools(tool1, tool2))
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ PrepareStep: prepareStepFunc,
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Len(t, capturedToolNames, 2) // All tools should be included
+ require.Contains(t, capturedToolNames, "tool1")
+ require.Contains(t, capturedToolNames, "tool2")
+ })
+}
+
+func TestToolCallRepair(t *testing.T) {
+ t.Parallel()
+
+ t.Run("Valid tool call passes validation", func(t *testing.T) {
+ t.Parallel()
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ return &Response{
+ Content: ResponseContent{
+ TextContent{Text: "Response"},
+ ToolCallContent{
+ ToolCallID: "call1",
+ ToolName: "test_tool",
+ Input: `{"value": "test"}`, // Valid JSON with required field
+ },
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonStop, // Changed to stop to avoid infinite loop
+ }, nil
+ },
+ }
+
+ tool := &mockTool{
+ name: "test_tool",
+ description: "Test tool",
+ parameters: map[string]any{
+ "value": map[string]any{"type": "string"},
+ },
+ required: []string{"value"},
+ executeFunc: func(ctx context.Context, call ToolCall) (ToolResponse, error) {
+ return ToolResponse{Content: "success", IsError: false}, nil
+ },
+ }
+
+ agent := NewAgent(model, WithTools(tool), WithStopConditions(StepCountIs(2))) // Limit steps
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Len(t, result.Steps, 1) // Only one step since FinishReason is stop
+
+ // Check that tool call was executed successfully
+ toolCalls := result.Steps[0].Content.ToolCalls()
+ require.Len(t, toolCalls, 1)
+ require.False(t, toolCalls[0].Invalid) // Should be valid
+ })
+
+ t.Run("Invalid tool call without repair function", func(t *testing.T) {
+ t.Parallel()
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ return &Response{
+ Content: ResponseContent{
+ TextContent{Text: "Response"},
+ ToolCallContent{
+ ToolCallID: "call1",
+ ToolName: "test_tool",
+ Input: `{"wrong_field": "test"}`, // Missing required field
+ },
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonStop, // Changed to stop to avoid infinite loop
+ }, nil
+ },
+ }
+
+ tool := &mockTool{
+ name: "test_tool",
+ description: "Test tool",
+ parameters: map[string]any{
+ "value": map[string]any{"type": "string"},
+ },
+ required: []string{"value"},
+ }
+
+ agent := NewAgent(model, WithTools(tool), WithStopConditions(StepCountIs(2))) // Limit steps
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Len(t, result.Steps, 1) // Only one step
+
+ // Check that tool call was marked as invalid
+ toolCalls := result.Steps[0].Content.ToolCalls()
+ require.Len(t, toolCalls, 1)
+ require.True(t, toolCalls[0].Invalid) // Should be invalid
+ require.Contains(t, toolCalls[0].ValidationError.Error(), "missing required parameter: value")
+ })
+
+ t.Run("Invalid tool call with successful repair", func(t *testing.T) {
+ t.Parallel()
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ return &Response{
+ Content: ResponseContent{
+ TextContent{Text: "Response"},
+ ToolCallContent{
+ ToolCallID: "call1",
+ ToolName: "test_tool",
+ Input: `{"wrong_field": "test"}`, // Missing required field
+ },
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonStop, // Changed to stop
+ }, nil
+ },
+ }
+
+ tool := &mockTool{
+ name: "test_tool",
+ description: "Test tool",
+ parameters: map[string]any{
+ "value": map[string]any{"type": "string"},
+ },
+ required: []string{"value"},
+ executeFunc: func(ctx context.Context, call ToolCall) (ToolResponse, error) {
+ return ToolResponse{Content: "repaired_success", IsError: false}, nil
+ },
+ }
+
+ repairFunc := func(ctx context.Context, options ToolCallRepairOptions) (*ToolCallContent, error) {
+ // Simple repair: add the missing required field
+ repairedToolCall := options.OriginalToolCall
+ repairedToolCall.Input = `{"value": "repaired"}`
+ return &repairedToolCall, nil
+ }
+
+ agent := NewAgent(model, WithTools(tool), WithRepairToolCall(repairFunc), WithStopConditions(StepCountIs(2)))
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Len(t, result.Steps, 1) // Only one step
+
+ // Check that tool call was repaired and is now valid
+ toolCalls := result.Steps[0].Content.ToolCalls()
+ require.Len(t, toolCalls, 1)
+ require.False(t, toolCalls[0].Invalid) // Should be valid after repair
+ require.Equal(t, `{"value": "repaired"}`, toolCalls[0].Input) // Should have repaired input
+ })
+
+ t.Run("Invalid tool call with failed repair", func(t *testing.T) {
+ t.Parallel()
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ return &Response{
+ Content: ResponseContent{
+ TextContent{Text: "Response"},
+ ToolCallContent{
+ ToolCallID: "call1",
+ ToolName: "test_tool",
+ Input: `{"wrong_field": "test"}`, // Missing required field
+ },
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonStop, // Changed to stop
+ }, nil
+ },
+ }
+
+ tool := &mockTool{
+ name: "test_tool",
+ description: "Test tool",
+ parameters: map[string]any{
+ "value": map[string]any{"type": "string"},
+ },
+ required: []string{"value"},
+ }
+
+ repairFunc := func(ctx context.Context, options ToolCallRepairOptions) (*ToolCallContent, error) {
+ // Repair function fails
+ return nil, errors.New("repair failed")
+ }
+
+ agent := NewAgent(model, WithTools(tool), WithRepairToolCall(repairFunc), WithStopConditions(StepCountIs(2)))
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Len(t, result.Steps, 1) // Only one step
+
+ // Check that tool call was marked as invalid since repair failed
+ toolCalls := result.Steps[0].Content.ToolCalls()
+ require.Len(t, toolCalls, 1)
+ require.True(t, toolCalls[0].Invalid) // Should be invalid
+ require.Contains(t, toolCalls[0].ValidationError.Error(), "missing required parameter: value")
+ })
+
+ t.Run("Nonexistent tool call", func(t *testing.T) {
+ t.Parallel()
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ return &Response{
+ Content: ResponseContent{
+ TextContent{Text: "Response"},
+ ToolCallContent{
+ ToolCallID: "call1",
+ ToolName: "nonexistent_tool",
+ Input: `{"value": "test"}`,
+ },
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonStop, // Changed to stop
+ }, nil
+ },
+ }
+
+ tool := &mockTool{name: "test_tool", description: "Test tool"}
+
+ agent := NewAgent(model, WithTools(tool), WithStopConditions(StepCountIs(2)))
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Len(t, result.Steps, 1) // Only one step
+
+ // Check that tool call was marked as invalid due to nonexistent tool
+ toolCalls := result.Steps[0].Content.ToolCalls()
+ require.Len(t, toolCalls, 1)
+ require.True(t, toolCalls[0].Invalid) // Should be invalid
+ require.Contains(t, toolCalls[0].ValidationError.Error(), "tool not found: nonexistent_tool")
+ })
+
+ t.Run("Invalid JSON in tool call", func(t *testing.T) {
+ t.Parallel()
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ return &Response{
+ Content: ResponseContent{
+ TextContent{Text: "Response"},
+ ToolCallContent{
+ ToolCallID: "call1",
+ ToolName: "test_tool",
+ Input: `{invalid json}`, // Invalid JSON
+ },
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonStop, // Changed to stop
+ }, nil
+ },
+ }
+
+ tool := &mockTool{
+ name: "test_tool",
+ description: "Test tool",
+ parameters: map[string]any{
+ "value": map[string]any{"type": "string"},
+ },
+ required: []string{"value"},
+ }
+
+ agent := NewAgent(model, WithTools(tool), WithStopConditions(StepCountIs(2)))
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "test prompt",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Len(t, result.Steps, 1) // Only one step
+
+ // Check that tool call was marked as invalid due to invalid JSON
+ toolCalls := result.Steps[0].Content.ToolCalls()
+ require.Len(t, toolCalls, 1)
+ require.True(t, toolCalls[0].Invalid) // Should be invalid
+ require.Contains(t, toolCalls[0].ValidationError.Error(), "invalid JSON input")
+ })
+}
+
+// Test media and image tool responses
+func TestAgent_MediaToolResponses(t *testing.T) {
+ t.Parallel()
+
+ imageData := []byte{0x89, 0x50, 0x4E, 0x47} // PNG header bytes
+ audioData := []byte{0x52, 0x49, 0x46, 0x46} // RIFF header bytes
+
+ t.Run("Image tool response", func(t *testing.T) {
+ t.Parallel()
+
+ imageTool := &mockTool{
+ name: "generate_image",
+ description: "Generates an image",
+ executeFunc: func(ctx context.Context, call ToolCall) (ToolResponse, error) {
+ return NewImageResponse(imageData, "image/png"), nil
+ },
+ }
+
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ if len(call.Prompt) == 1 {
+ // First call - request image tool
+ return &Response{
+ Content: []Content{
+ ToolCallContent{
+ ToolCallID: "img-1",
+ ToolName: "generate_image",
+ Input: `{}`,
+ },
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonToolCalls,
+ }, nil
+ }
+ // Second call - after tool execution
+ return &Response{
+ Content: []Content{TextContent{Text: "Image generated"}},
+ Usage: Usage{TotalTokens: 20},
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ agent := NewAgent(model, WithTools(imageTool), WithStopConditions(StepCountIs(3)))
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "Generate an image",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+ require.Len(t, result.Steps, 2) // Tool call step + final response
+
+ // Check tool results in first step
+ toolResults := result.Steps[0].Content.ToolResults()
+ require.Len(t, toolResults, 1)
+
+ mediaResult, ok := toolResults[0].Result.(ToolResultOutputContentMedia)
+ require.True(t, ok, "Expected media result")
+ require.Equal(t, string(imageData), mediaResult.Data)
+ require.Equal(t, "image/png", mediaResult.MediaType)
+ })
+
+ t.Run("Media tool response (audio)", func(t *testing.T) {
+ t.Parallel()
+
+ audioTool := &mockTool{
+ name: "generate_audio",
+ description: "Generates audio",
+ executeFunc: func(ctx context.Context, call ToolCall) (ToolResponse, error) {
+ return NewMediaResponse(audioData, "audio/wav"), nil
+ },
+ }
+
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ if len(call.Prompt) == 1 {
+ return &Response{
+ Content: []Content{
+ ToolCallContent{
+ ToolCallID: "audio-1",
+ ToolName: "generate_audio",
+ Input: `{}`,
+ },
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonToolCalls,
+ }, nil
+ }
+ return &Response{
+ Content: []Content{TextContent{Text: "Audio generated"}},
+ Usage: Usage{TotalTokens: 20},
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ agent := NewAgent(model, WithTools(audioTool), WithStopConditions(StepCountIs(3)))
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "Generate audio",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+
+ toolResults := result.Steps[0].Content.ToolResults()
+ require.Len(t, toolResults, 1)
+
+ mediaResult, ok := toolResults[0].Result.(ToolResultOutputContentMedia)
+ require.True(t, ok, "Expected media result")
+ require.Equal(t, string(audioData), mediaResult.Data)
+ require.Equal(t, "audio/wav", mediaResult.MediaType)
+ })
+
+ t.Run("Media response with text", func(t *testing.T) {
+ t.Parallel()
+
+ imageTool := &mockTool{
+ name: "screenshot",
+ description: "Takes a screenshot",
+ executeFunc: func(ctx context.Context, call ToolCall) (ToolResponse, error) {
+ resp := NewImageResponse(imageData, "image/png")
+ resp.Content = "Screenshot captured successfully"
+ return resp, nil
+ },
+ }
+
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ if len(call.Prompt) == 1 {
+ return &Response{
+ Content: []Content{
+ ToolCallContent{
+ ToolCallID: "screen-1",
+ ToolName: "screenshot",
+ Input: `{}`,
+ },
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonToolCalls,
+ }, nil
+ }
+ return &Response{
+ Content: []Content{TextContent{Text: "Done"}},
+ Usage: Usage{TotalTokens: 20},
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ agent := NewAgent(model, WithTools(imageTool), WithStopConditions(StepCountIs(3)))
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "Take a screenshot",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+
+ toolResults := result.Steps[0].Content.ToolResults()
+ require.Len(t, toolResults, 1)
+
+ mediaResult, ok := toolResults[0].Result.(ToolResultOutputContentMedia)
+ require.True(t, ok, "Expected media result")
+ require.Equal(t, string(imageData), mediaResult.Data)
+ require.Equal(t, "image/png", mediaResult.MediaType)
+ require.Equal(t, "Screenshot captured successfully", mediaResult.Text)
+ })
+
+ t.Run("Media response preserves metadata", func(t *testing.T) {
+ t.Parallel()
+
+ type ImageMetadata struct {
+ Width int `json:"width"`
+ Height int `json:"height"`
+ }
+
+ imageTool := &mockTool{
+ name: "generate_image",
+ description: "Generates an image",
+ executeFunc: func(ctx context.Context, call ToolCall) (ToolResponse, error) {
+ resp := NewImageResponse(imageData, "image/png")
+ return WithResponseMetadata(resp, ImageMetadata{Width: 800, Height: 600}), nil
+ },
+ }
+
+ model := &mockLanguageModel{
+ generateFunc: func(ctx context.Context, call Call) (*Response, error) {
+ if len(call.Prompt) == 1 {
+ return &Response{
+ Content: []Content{
+ ToolCallContent{
+ ToolCallID: "img-1",
+ ToolName: "generate_image",
+ Input: `{}`,
+ },
+ },
+ Usage: Usage{TotalTokens: 10},
+ FinishReason: FinishReasonToolCalls,
+ }, nil
+ }
+ return &Response{
+ Content: []Content{TextContent{Text: "Done"}},
+ Usage: Usage{TotalTokens: 20},
+ FinishReason: FinishReasonStop,
+ }, nil
+ },
+ }
+
+ agent := NewAgent(model, WithTools(imageTool), WithStopConditions(StepCountIs(3)))
+
+ result, err := agent.Generate(context.Background(), AgentCall{
+ Prompt: "Generate image",
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result)
+
+ toolResults := result.Steps[0].Content.ToolResults()
+ require.Len(t, toolResults, 1)
+
+ // Check metadata was preserved
+ require.NotEmpty(t, toolResults[0].ClientMetadata)
+
+ var metadata ImageMetadata
+ err = json.Unmarshal([]byte(toolResults[0].ClientMetadata), &metadata)
+ require.NoError(t, err)
+ require.Equal(t, 800, metadata.Width)
+ require.Equal(t, 600, metadata.Height)
+ })
+}
diff --git a/internal/fantasy/content.go b/internal/fantasy/content.go
new file mode 100644
index 000000000..0edd8410e
--- /dev/null
+++ b/internal/fantasy/content.go
@@ -0,0 +1,560 @@
+package fantasy
+
+import "encoding/json"
+
+// ProviderOptionsData is an interface for provider-specific options data.
+// All implementations MUST also implement encoding/json.Marshaler and
+// encoding/json.Unmarshaler interfaces to ensure proper JSON serialization
+// with the provider registry system.
+//
+// Recommended implementation pattern using generic helpers:
+//
+// // Define type constants at the top of your file
+// const TypeMyProviderOptions = "myprovider.options"
+//
+// type MyProviderOptions struct {
+// Field string `json:"field"`
+// }
+//
+// // Register the type in init() - place at top of file after constants
+// func init() {
+// fantasy.RegisterProviderType(TypeMyProviderOptions, func(data []byte) (fantasy.ProviderOptionsData, error) {
+// var opts MyProviderOptions
+// if err := json.Unmarshal(data, &opts); err != nil {
+// return nil, err
+// }
+// return &opts, nil
+// })
+// }
+//
+// // Implement ProviderOptionsData interface
+// func (*MyProviderOptions) Options() {}
+//
+// // Implement json.Marshaler using the generic helper
+// func (m MyProviderOptions) MarshalJSON() ([]byte, error) {
+// type plain MyProviderOptions
+// return fantasy.MarshalProviderType(TypeMyProviderOptions, plain(m))
+// }
+//
+// // Implement json.Unmarshaler using the generic helper
+// // Note: Receives inner data after type routing by the registry.
+// func (m *MyProviderOptions) UnmarshalJSON(data []byte) error {
+// type plain MyProviderOptions
+// var p plain
+// if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+// return err
+// }
+// *m = MyProviderOptions(p)
+// return nil
+// }
+type ProviderOptionsData interface {
+ // Options is a marker method that identifies types implementing this interface.
+ Options()
+ json.Marshaler
+ json.Unmarshaler
+}
+
+// ProviderMetadata represents additional provider-specific metadata.
+// They are passed through from the provider to the AI SDK and enable
+// provider-specific results that can be fully encapsulated in the provider.
+//
+// The outer map is keyed by the provider name, and the inner
+// map is keyed by the provider-specific metadata key.
+//
+// Example:
+//
+// {
+// "anthropic": {
+// "signature": "sig....."
+// }
+// }
+type ProviderMetadata map[string]ProviderOptionsData
+
+// ProviderOptions represents additional provider-specific options.
+// Options are additional input to the provider. They are passed through
+// to the provider from the AI SDK and enable provider-specific functionality
+// that can be fully encapsulated in the provider.
+//
+// This enables us to quickly ship provider-specific functionality
+// without affecting the core AI SDK.
+//
+// The outer map is keyed by the provider name, and the inner
+// map is keyed by the provider-specific option key.
+//
+// Example:
+//
+// {
+// "anthropic": {
+// "cacheControl": { "type": "ephemeral" }
+// }
+// }
+type ProviderOptions map[string]ProviderOptionsData
+
+// FinishReason represents why a language model finished generating a response.
+//
+// Can be one of the following:
+// - `stop`: model generated stop sequence
+// - `length`: model generated maximum number of tokens
+// - `content-filter`: content filter violation stopped the model
+// - `tool-calls`: model triggered tool calls
+// - `error`: model stopped because of an error
+// - `other`: model stopped for other reasons
+// - `unknown`: the model has not transmitted a finish reason.
+type FinishReason string
+
+const (
+ // FinishReasonStop indicates the model generated a stop sequence.
+ FinishReasonStop FinishReason = "stop" // model generated stop sequence
+ // FinishReasonLength indicates the model generated maximum number of tokens.
+ FinishReasonLength FinishReason = "length" // model generated maximum number of tokens
+ // FinishReasonContentFilter indicates content filter violation stopped the model.
+ FinishReasonContentFilter FinishReason = "content-filter" // content filter violation stopped the model
+ // FinishReasonToolCalls indicates the model triggered tool calls.
+ FinishReasonToolCalls FinishReason = "tool-calls" // model triggered tool calls
+ // FinishReasonError indicates the model stopped because of an error.
+ FinishReasonError FinishReason = "error" // model stopped because of an error
+ // FinishReasonOther indicates the model stopped for other reasons.
+ FinishReasonOther FinishReason = "other" // model stopped for other reasons
+ // FinishReasonUnknown indicates the model has not transmitted a finish reason.
+ FinishReasonUnknown FinishReason = "unknown" // the model has not transmitted a finish reason
+)
+
+// Prompt represents a list of messages for the language model.
+type Prompt []Message
+
+// MessageRole represents the role of a message.
+type MessageRole string
+
+const (
+ // MessageRoleSystem represents a system message.
+ MessageRoleSystem MessageRole = "system"
+ // MessageRoleUser represents a user message.
+ MessageRoleUser MessageRole = "user"
+ // MessageRoleAssistant represents an assistant message.
+ MessageRoleAssistant MessageRole = "assistant"
+ // MessageRoleTool represents a tool message.
+ MessageRoleTool MessageRole = "tool"
+)
+
+// Message represents a message in a prompt.
+type Message struct {
+ Role MessageRole `json:"role"`
+ Content []MessagePart `json:"content"`
+ ProviderOptions ProviderOptions `json:"provider_options"`
+}
+
+// AsContentType converts a Content interface to a specific content type.
+func AsContentType[T Content](content Content) (T, bool) {
+ var zero T
+ if content == nil {
+ return zero, false
+ }
+ switch v := any(content).(type) {
+ case T:
+ return v, true
+ case *T:
+ return *v, true
+ default:
+ return zero, false
+ }
+}
+
+// AsMessagePart converts a MessagePart interface to a specific message part type.
+func AsMessagePart[T MessagePart](content MessagePart) (T, bool) {
+ var zero T
+ if content == nil {
+ return zero, false
+ }
+ switch v := any(content).(type) {
+ case T:
+ return v, true
+ case *T:
+ return *v, true
+ default:
+ return zero, false
+ }
+}
+
+// MessagePart represents a part of a message content.
+type MessagePart interface {
+ GetType() ContentType
+ Options() ProviderOptions
+}
+
+// TextPart represents text content in a message.
+type TextPart struct {
+ Text string `json:"text"`
+ ProviderOptions ProviderOptions `json:"provider_options"`
+}
+
+// GetType returns the type of the text part.
+func (t TextPart) GetType() ContentType {
+ return ContentTypeText
+}
+
+// Options returns the provider options for the text part.
+func (t TextPart) Options() ProviderOptions {
+ return t.ProviderOptions
+}
+
+// ReasoningPart represents reasoning content in a message.
+type ReasoningPart struct {
+ Text string `json:"text"`
+ ProviderOptions ProviderOptions `json:"provider_options"`
+}
+
+// GetType returns the type of the reasoning part.
+func (r ReasoningPart) GetType() ContentType {
+ return ContentTypeReasoning
+}
+
+// Options returns the provider options for the reasoning part.
+func (r ReasoningPart) Options() ProviderOptions {
+ return r.ProviderOptions
+}
+
+// FilePart represents file content in a message.
+type FilePart struct {
+ Filename string `json:"filename"`
+ Data []byte `json:"data"`
+ MediaType string `json:"media_type"`
+ ProviderOptions ProviderOptions `json:"provider_options"`
+}
+
+// GetType returns the type of the file part.
+func (f FilePart) GetType() ContentType {
+ return ContentTypeFile
+}
+
+// Options returns the provider options for the file part.
+func (f FilePart) Options() ProviderOptions {
+ return f.ProviderOptions
+}
+
+// ToolCallPart represents a tool call in a message.
+type ToolCallPart struct {
+ ToolCallID string `json:"tool_call_id"`
+ ToolName string `json:"tool_name"`
+ Input string `json:"input"` // the json string
+ ProviderExecuted bool `json:"provider_executed"`
+ ProviderOptions ProviderOptions `json:"provider_options"`
+}
+
+// GetType returns the type of the tool call part.
+func (t ToolCallPart) GetType() ContentType {
+ return ContentTypeToolCall
+}
+
+// Options returns the provider options for the tool call part.
+func (t ToolCallPart) Options() ProviderOptions {
+ return t.ProviderOptions
+}
+
+// ToolResultPart represents a tool result in a message.
+type ToolResultPart struct {
+ ToolCallID string `json:"tool_call_id"`
+ Output ToolResultOutputContent `json:"output"`
+ ProviderOptions ProviderOptions `json:"provider_options"`
+}
+
+// GetType returns the type of the tool result part.
+func (t ToolResultPart) GetType() ContentType {
+ return ContentTypeToolResult
+}
+
+// Options returns the provider options for the tool result part.
+func (t ToolResultPart) Options() ProviderOptions {
+ return t.ProviderOptions
+}
+
+// ToolResultContentType represents the type of tool result output.
+type ToolResultContentType string
+
+const (
+ // ToolResultContentTypeText represents text output.
+ ToolResultContentTypeText ToolResultContentType = "text"
+ // ToolResultContentTypeError represents error text output.
+ ToolResultContentTypeError ToolResultContentType = "error"
+ // ToolResultContentTypeMedia represents content output.
+ ToolResultContentTypeMedia ToolResultContentType = "media"
+)
+
+// ToolResultOutputContent represents the output content of a tool result.
+type ToolResultOutputContent interface {
+ GetType() ToolResultContentType
+}
+
+// ToolResultOutputContentText represents text output content of a tool result.
+type ToolResultOutputContentText struct {
+ Text string `json:"text"`
+}
+
+// GetType returns the type of the tool result output content text.
+func (t ToolResultOutputContentText) GetType() ToolResultContentType {
+ return ToolResultContentTypeText
+}
+
+// ToolResultOutputContentError represents error output content of a tool result.
+type ToolResultOutputContentError struct {
+ Error error `json:"error"`
+}
+
+// GetType returns the type of the tool result output content error.
+func (t ToolResultOutputContentError) GetType() ToolResultContentType {
+ return ToolResultContentTypeError
+}
+
+// ToolResultOutputContentMedia represents media output content of a tool result.
+type ToolResultOutputContentMedia struct {
+ Data string `json:"data"` // for media type (base64)
+ MediaType string `json:"media_type"` // for media type
+ Text string `json:"text,omitempty"` // optional text content accompanying the media
+}
+
+// GetType returns the type of the tool result output content media.
+func (t ToolResultOutputContentMedia) GetType() ToolResultContentType {
+ return ToolResultContentTypeMedia
+}
+
+// AsToolResultOutputType converts a ToolResultOutputContent interface to a specific type.
+func AsToolResultOutputType[T ToolResultOutputContent](content ToolResultOutputContent) (T, bool) {
+ var zero T
+ if content == nil {
+ return zero, false
+ }
+ switch v := any(content).(type) {
+ case T:
+ return v, true
+ case *T:
+ return *v, true
+ default:
+ return zero, false
+ }
+}
+
+// ContentType represents the type of content.
+type ContentType string
+
+const (
+ // ContentTypeText represents text content.
+ ContentTypeText ContentType = "text"
+ // ContentTypeReasoning represents reasoning content.
+ ContentTypeReasoning ContentType = "reasoning"
+ // ContentTypeFile represents file content.
+ ContentTypeFile ContentType = "file"
+ // ContentTypeSource represents source content.
+ ContentTypeSource ContentType = "source"
+ // ContentTypeToolCall represents a tool call.
+ ContentTypeToolCall ContentType = "tool-call"
+ // ContentTypeToolResult represents a tool result.
+ ContentTypeToolResult ContentType = "tool-result"
+)
+
+// Content represents generated content from the model.
+type Content interface {
+ GetType() ContentType
+}
+
+// TextContent represents text that the model has generated.
+type TextContent struct {
+ // The text content.
+ Text string `json:"text"`
+ ProviderMetadata ProviderMetadata `json:"provider_metadata"`
+}
+
+// GetType returns the type of the text content.
+func (t TextContent) GetType() ContentType {
+ return ContentTypeText
+}
+
+// ReasoningContent represents reasoning that the model has generated.
+type ReasoningContent struct {
+ Text string `json:"text"`
+ ProviderMetadata ProviderMetadata `json:"provider_metadata"`
+}
+
+// GetType returns the type of the reasoning content.
+func (r ReasoningContent) GetType() ContentType {
+ return ContentTypeReasoning
+}
+
+// FileContent represents a file that has been generated by the model.
+// Generated files as base64 encoded strings or binary data.
+// The files should be returned without any unnecessary conversion.
+type FileContent struct {
+ // The IANA media type of the file, e.g. `image/png` or `audio/mp3`.
+ // @see https://www.iana.org/assignments/media-types/media-types.xhtml
+ MediaType string `json:"media_type"`
+ // Generated file data as binary data.
+ Data []byte `json:"data"`
+ ProviderMetadata ProviderMetadata `json:"provider_metadata"`
+}
+
+// GetType returns the type of the file content.
+func (f FileContent) GetType() ContentType {
+ return ContentTypeFile
+}
+
+// SourceType represents the type of source.
+type SourceType string
+
+const (
+ // SourceTypeURL represents a URL source.
+ SourceTypeURL SourceType = "url"
+ // SourceTypeDocument represents a document source.
+ SourceTypeDocument SourceType = "document"
+)
+
+// SourceContent represents a source that has been used as input to generate the response.
+type SourceContent struct {
+ SourceType SourceType `json:"source_type"` // "url" or "document"
+ ID string `json:"id"`
+ URL string `json:"url"` // for URL sources
+ Title string `json:"title"`
+ MediaType string `json:"media_type"` // for document sources (IANA media type)
+ Filename string `json:"filename"` // for document sources
+ ProviderMetadata ProviderMetadata `json:"provider_metadata"`
+}
+
+// GetType returns the type of the source content.
+func (s SourceContent) GetType() ContentType {
+ return ContentTypeSource
+}
+
+// ToolCallContent represents tool calls that the model has generated.
+type ToolCallContent struct {
+ ToolCallID string `json:"tool_call_id"`
+ ToolName string `json:"tool_name"`
+ // Stringified JSON object with the tool call arguments.
+ // Must match the parameters schema of the tool.
+ Input string `json:"input"`
+ // Whether the tool call will be executed by the provider.
+ // If this flag is not set or is false, the tool call will be executed by the client.
+ ProviderExecuted bool `json:"provider_executed"`
+ // Additional provider-specific metadata for the tool call.
+ ProviderMetadata ProviderMetadata `json:"provider_metadata"`
+ // Whether this tool call is invalid (failed validation/parsing)
+ Invalid bool `json:"invalid,omitempty"`
+ // Error that occurred during validation/parsing (only set if Invalid is true)
+ ValidationError error `json:"validation_error,omitempty"`
+}
+
+// GetType returns the type of the tool call content.
+func (t ToolCallContent) GetType() ContentType {
+ return ContentTypeToolCall
+}
+
+// ToolResultContent represents result of a tool call that has been executed by the provider.
+type ToolResultContent struct {
+ // The ID of the tool call that this result is associated with.
+ ToolCallID string `json:"tool_call_id"`
+ // Name of the tool that generated this result.
+ ToolName string `json:"tool_name"`
+ // Result of the tool call. This is a JSON-serializable object.
+ Result ToolResultOutputContent `json:"result"`
+ ClientMetadata string `json:"client_metadata"` // Metadata from the client that executed the tool
+ // Whether the tool result was generated by the provider.
+ // If this flag is set to true, the tool result was generated by the provider.
+ // If this flag is not set or is false, the tool result was generated by the client.
+ ProviderExecuted bool `json:"provider_executed"`
+ // Additional provider-specific metadata for the tool result.
+ ProviderMetadata ProviderMetadata `json:"provider_metadata"`
+}
+
+// GetType returns the type of the tool result content.
+func (t ToolResultContent) GetType() ContentType {
+ return ContentTypeToolResult
+}
+
+// ToolType represents the type of tool.
+type ToolType string
+
+const (
+ // ToolTypeFunction represents a function tool.
+ ToolTypeFunction ToolType = "function"
+ // ToolTypeProviderDefined represents a provider-defined tool.
+ ToolTypeProviderDefined ToolType = "provider-defined"
+)
+
+// Tool represents a tool that can be used by the model.
+//
+// Note: this is **not** the user-facing tool definition. The AI SDK methods will
+// map the user-facing tool definitions to this format.
+type Tool interface {
+ GetType() ToolType
+ GetName() string
+}
+
+// FunctionTool represents a function tool.
+//
+// A tool has a name, a description, and a set of parameters.
+type FunctionTool struct {
+ // Name of the tool. Unique within this model call.
+ Name string `json:"name"`
+ // Description of the tool. The language model uses this to understand the
+ // tool's purpose and to provide better completion suggestions.
+ Description string `json:"description"`
+ // InputSchema - the parameters that the tool expects. The language model uses this to
+ // understand the tool's input requirements and to provide matching suggestions.
+ InputSchema map[string]any `json:"input_schema"` // JSON Schema
+ // ProviderOptions are provider-specific options for the tool.
+ ProviderOptions ProviderOptions `json:"provider_options"`
+}
+
+// GetType returns the type of the function tool.
+func (f FunctionTool) GetType() ToolType {
+ return ToolTypeFunction
+}
+
+// GetName returns the name of the function tool.
+func (f FunctionTool) GetName() string {
+ return f.Name
+}
+
+// ProviderDefinedTool represents the configuration of a tool that is defined by the provider.
+type ProviderDefinedTool struct {
+ // ID of the tool. Should follow the format `.`.
+ ID string `json:"id"`
+ // Name of the tool that the user must use in the tool set.
+ Name string `json:"name"`
+ // Args for configuring the tool. Must match the expected arguments defined by the provider for this tool.
+ Args map[string]any `json:"args"`
+}
+
+// GetType returns the type of the provider-defined tool.
+func (p ProviderDefinedTool) GetType() ToolType {
+ return ToolTypeProviderDefined
+}
+
+// GetName returns the name of the provider-defined tool.
+func (p ProviderDefinedTool) GetName() string {
+ return p.Name
+}
+
+// NewUserMessage creates a new user message with the given prompt and optional files.
+func NewUserMessage(prompt string, files ...FilePart) Message {
+ content := make([]MessagePart, 0, len(files)+1)
+ content = append(content, TextPart{Text: prompt})
+
+ for _, f := range files {
+ content = append(content, f)
+ }
+
+ return Message{
+ Role: MessageRoleUser,
+ Content: content,
+ }
+}
+
+// NewSystemMessage creates a new system message with the given prompts.
+func NewSystemMessage(prompt ...string) Message {
+ content := make([]MessagePart, 0, len(prompt))
+ for _, p := range prompt {
+ content = append(content, TextPart{Text: p})
+ }
+
+ return Message{
+ Role: MessageRoleSystem,
+ Content: content,
+ }
+}
diff --git a/internal/fantasy/content_json.go b/internal/fantasy/content_json.go
new file mode 100644
index 000000000..1f2d53ed0
--- /dev/null
+++ b/internal/fantasy/content_json.go
@@ -0,0 +1,1038 @@
+package fantasy
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+)
+
+// contentJSON is a helper type for JSON serialization of Content in Response.
+type contentJSON struct {
+ Type string `json:"type"`
+ Data json.RawMessage `json:"data"`
+}
+
+// messagePartJSON is a helper type for JSON serialization of MessagePart.
+type messagePartJSON struct {
+ Type string `json:"type"`
+ Data json.RawMessage `json:"data"`
+}
+
+// toolResultOutputJSON is a helper type for JSON serialization of ToolResultOutputContent.
+type toolResultOutputJSON struct {
+ Type string `json:"type"`
+ Data json.RawMessage `json:"data"`
+}
+
+// toolJSON is a helper type for JSON serialization of Tool.
+type toolJSON struct {
+ Type string `json:"type"`
+ Data json.RawMessage `json:"data"`
+}
+
+// MarshalJSON implements json.Marshaler for TextContent.
+func (t TextContent) MarshalJSON() ([]byte, error) {
+ dataBytes, err := json.Marshal(struct {
+ Text string `json:"text"`
+ ProviderMetadata ProviderMetadata `json:"provider_metadata,omitempty"`
+ }{
+ Text: t.Text,
+ ProviderMetadata: t.ProviderMetadata,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(contentJSON{
+ Type: string(ContentTypeText),
+ Data: json.RawMessage(dataBytes),
+ })
+}
+
+// UnmarshalJSON implements json.Unmarshaler for TextContent.
+func (t *TextContent) UnmarshalJSON(data []byte) error {
+ var cj contentJSON
+ if err := json.Unmarshal(data, &cj); err != nil {
+ return err
+ }
+
+ var aux struct {
+ Text string `json:"text"`
+ ProviderMetadata map[string]json.RawMessage `json:"provider_metadata,omitempty"`
+ }
+
+ if err := json.Unmarshal(cj.Data, &aux); err != nil {
+ return err
+ }
+
+ t.Text = aux.Text
+
+ if len(aux.ProviderMetadata) > 0 {
+ metadata, err := UnmarshalProviderMetadata(aux.ProviderMetadata)
+ if err != nil {
+ return err
+ }
+ t.ProviderMetadata = metadata
+ }
+
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler for ReasoningContent.
+func (r ReasoningContent) MarshalJSON() ([]byte, error) {
+ dataBytes, err := json.Marshal(struct {
+ Text string `json:"text"`
+ ProviderMetadata ProviderMetadata `json:"provider_metadata,omitempty"`
+ }{
+ Text: r.Text,
+ ProviderMetadata: r.ProviderMetadata,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(contentJSON{
+ Type: string(ContentTypeReasoning),
+ Data: json.RawMessage(dataBytes),
+ })
+}
+
+// UnmarshalJSON implements json.Unmarshaler for ReasoningContent.
+func (r *ReasoningContent) UnmarshalJSON(data []byte) error {
+ var cj contentJSON
+ if err := json.Unmarshal(data, &cj); err != nil {
+ return err
+ }
+
+ var aux struct {
+ Text string `json:"text"`
+ ProviderMetadata map[string]json.RawMessage `json:"provider_metadata,omitempty"`
+ }
+
+ if err := json.Unmarshal(cj.Data, &aux); err != nil {
+ return err
+ }
+
+ r.Text = aux.Text
+
+ if len(aux.ProviderMetadata) > 0 {
+ metadata, err := UnmarshalProviderMetadata(aux.ProviderMetadata)
+ if err != nil {
+ return err
+ }
+ r.ProviderMetadata = metadata
+ }
+
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler for FileContent.
+func (f FileContent) MarshalJSON() ([]byte, error) {
+ dataBytes, err := json.Marshal(struct {
+ MediaType string `json:"media_type"`
+ Data []byte `json:"data"`
+ ProviderMetadata ProviderMetadata `json:"provider_metadata,omitempty"`
+ }{
+ MediaType: f.MediaType,
+ Data: f.Data,
+ ProviderMetadata: f.ProviderMetadata,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(contentJSON{
+ Type: string(ContentTypeFile),
+ Data: json.RawMessage(dataBytes),
+ })
+}
+
+// UnmarshalJSON implements json.Unmarshaler for FileContent.
+func (f *FileContent) UnmarshalJSON(data []byte) error {
+ var cj contentJSON
+ if err := json.Unmarshal(data, &cj); err != nil {
+ return err
+ }
+
+ var aux struct {
+ MediaType string `json:"media_type"`
+ Data []byte `json:"data"`
+ ProviderMetadata map[string]json.RawMessage `json:"provider_metadata,omitempty"`
+ }
+
+ if err := json.Unmarshal(cj.Data, &aux); err != nil {
+ return err
+ }
+
+ f.MediaType = aux.MediaType
+ f.Data = aux.Data
+
+ if len(aux.ProviderMetadata) > 0 {
+ metadata, err := UnmarshalProviderMetadata(aux.ProviderMetadata)
+ if err != nil {
+ return err
+ }
+ f.ProviderMetadata = metadata
+ }
+
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler for SourceContent.
+func (s SourceContent) MarshalJSON() ([]byte, error) {
+ dataBytes, err := json.Marshal(struct {
+ SourceType SourceType `json:"source_type"`
+ ID string `json:"id"`
+ URL string `json:"url,omitempty"`
+ Title string `json:"title,omitempty"`
+ MediaType string `json:"media_type,omitempty"`
+ Filename string `json:"filename,omitempty"`
+ ProviderMetadata ProviderMetadata `json:"provider_metadata,omitempty"`
+ }{
+ SourceType: s.SourceType,
+ ID: s.ID,
+ URL: s.URL,
+ Title: s.Title,
+ MediaType: s.MediaType,
+ Filename: s.Filename,
+ ProviderMetadata: s.ProviderMetadata,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(contentJSON{
+ Type: string(ContentTypeSource),
+ Data: json.RawMessage(dataBytes),
+ })
+}
+
+// UnmarshalJSON implements json.Unmarshaler for SourceContent.
+func (s *SourceContent) UnmarshalJSON(data []byte) error {
+ var cj contentJSON
+ if err := json.Unmarshal(data, &cj); err != nil {
+ return err
+ }
+
+ var aux struct {
+ SourceType SourceType `json:"source_type"`
+ ID string `json:"id"`
+ URL string `json:"url,omitempty"`
+ Title string `json:"title,omitempty"`
+ MediaType string `json:"media_type,omitempty"`
+ Filename string `json:"filename,omitempty"`
+ ProviderMetadata map[string]json.RawMessage `json:"provider_metadata,omitempty"`
+ }
+
+ if err := json.Unmarshal(cj.Data, &aux); err != nil {
+ return err
+ }
+
+ s.SourceType = aux.SourceType
+ s.ID = aux.ID
+ s.URL = aux.URL
+ s.Title = aux.Title
+ s.MediaType = aux.MediaType
+ s.Filename = aux.Filename
+
+ if len(aux.ProviderMetadata) > 0 {
+ metadata, err := UnmarshalProviderMetadata(aux.ProviderMetadata)
+ if err != nil {
+ return err
+ }
+ s.ProviderMetadata = metadata
+ }
+
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler for ToolCallContent.
+func (t ToolCallContent) MarshalJSON() ([]byte, error) {
+ var validationErrMsg *string
+ if t.ValidationError != nil {
+ msg := t.ValidationError.Error()
+ validationErrMsg = &msg
+ }
+ dataBytes, err := json.Marshal(struct {
+ ToolCallID string `json:"tool_call_id"`
+ ToolName string `json:"tool_name"`
+ Input string `json:"input"`
+ ProviderExecuted bool `json:"provider_executed"`
+ ProviderMetadata ProviderMetadata `json:"provider_metadata,omitempty"`
+ Invalid bool `json:"invalid,omitempty"`
+ ValidationError *string `json:"validation_error,omitempty"`
+ }{
+ ToolCallID: t.ToolCallID,
+ ToolName: t.ToolName,
+ Input: t.Input,
+ ProviderExecuted: t.ProviderExecuted,
+ ProviderMetadata: t.ProviderMetadata,
+ Invalid: t.Invalid,
+ ValidationError: validationErrMsg,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(contentJSON{
+ Type: string(ContentTypeToolCall),
+ Data: json.RawMessage(dataBytes),
+ })
+}
+
+// UnmarshalJSON implements json.Unmarshaler for ToolCallContent.
+func (t *ToolCallContent) UnmarshalJSON(data []byte) error {
+ var cj contentJSON
+ if err := json.Unmarshal(data, &cj); err != nil {
+ return err
+ }
+
+ var aux struct {
+ ToolCallID string `json:"tool_call_id"`
+ ToolName string `json:"tool_name"`
+ Input string `json:"input"`
+ ProviderExecuted bool `json:"provider_executed"`
+ ProviderMetadata map[string]json.RawMessage `json:"provider_metadata,omitempty"`
+ Invalid bool `json:"invalid,omitempty"`
+ ValidationError *string `json:"validation_error,omitempty"`
+ }
+
+ if err := json.Unmarshal(cj.Data, &aux); err != nil {
+ return err
+ }
+
+ t.ToolCallID = aux.ToolCallID
+ t.ToolName = aux.ToolName
+ t.Input = aux.Input
+ t.ProviderExecuted = aux.ProviderExecuted
+ t.Invalid = aux.Invalid
+ if aux.ValidationError != nil {
+ t.ValidationError = errors.New(*aux.ValidationError)
+ }
+
+ if len(aux.ProviderMetadata) > 0 {
+ metadata, err := UnmarshalProviderMetadata(aux.ProviderMetadata)
+ if err != nil {
+ return err
+ }
+ t.ProviderMetadata = metadata
+ }
+
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler for ToolResultContent.
+func (t ToolResultContent) MarshalJSON() ([]byte, error) {
+ dataBytes, err := json.Marshal(struct {
+ ToolCallID string `json:"tool_call_id"`
+ ToolName string `json:"tool_name"`
+ Result ToolResultOutputContent `json:"result"`
+ ClientMetadata string `json:"client_metadata,omitempty"`
+ ProviderExecuted bool `json:"provider_executed"`
+ ProviderMetadata ProviderMetadata `json:"provider_metadata,omitempty"`
+ }{
+ ToolCallID: t.ToolCallID,
+ ToolName: t.ToolName,
+ Result: t.Result,
+ ClientMetadata: t.ClientMetadata,
+ ProviderExecuted: t.ProviderExecuted,
+ ProviderMetadata: t.ProviderMetadata,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(contentJSON{
+ Type: string(ContentTypeToolResult),
+ Data: json.RawMessage(dataBytes),
+ })
+}
+
+// UnmarshalJSON implements json.Unmarshaler for ToolResultContent.
+func (t *ToolResultContent) UnmarshalJSON(data []byte) error {
+ var cj contentJSON
+ if err := json.Unmarshal(data, &cj); err != nil {
+ return err
+ }
+
+ var aux struct {
+ ToolCallID string `json:"tool_call_id"`
+ ToolName string `json:"tool_name"`
+ Result json.RawMessage `json:"result"`
+ ClientMetadata string `json:"client_metadata,omitempty"`
+ ProviderExecuted bool `json:"provider_executed"`
+ ProviderMetadata map[string]json.RawMessage `json:"provider_metadata,omitempty"`
+ }
+
+ if err := json.Unmarshal(cj.Data, &aux); err != nil {
+ return err
+ }
+
+ t.ToolCallID = aux.ToolCallID
+ t.ToolName = aux.ToolName
+ t.ClientMetadata = aux.ClientMetadata
+ t.ProviderExecuted = aux.ProviderExecuted
+
+ // Unmarshal the Result field
+ result, err := UnmarshalToolResultOutputContent(aux.Result)
+ if err != nil {
+ return fmt.Errorf("failed to unmarshal tool result output: %w", err)
+ }
+ t.Result = result
+
+ if len(aux.ProviderMetadata) > 0 {
+ metadata, err := UnmarshalProviderMetadata(aux.ProviderMetadata)
+ if err != nil {
+ return err
+ }
+ t.ProviderMetadata = metadata
+ }
+
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler for ToolResultOutputContentText.
+func (t ToolResultOutputContentText) MarshalJSON() ([]byte, error) {
+ type alias ToolResultOutputContentText
+ dataBytes, err := json.Marshal(alias(t))
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(toolResultOutputJSON{
+ Type: string(ToolResultContentTypeText),
+ Data: json.RawMessage(dataBytes),
+ })
+}
+
+// UnmarshalJSON implements json.Unmarshaler for ToolResultOutputContentText.
+func (t *ToolResultOutputContentText) UnmarshalJSON(data []byte) error {
+ var tr toolResultOutputJSON
+ if err := json.Unmarshal(data, &tr); err != nil {
+ return err
+ }
+
+ type alias ToolResultOutputContentText
+ var temp alias
+
+ if err := json.Unmarshal(tr.Data, &temp); err != nil {
+ return err
+ }
+
+ *t = ToolResultOutputContentText(temp)
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler for ToolResultOutputContentError.
+func (t ToolResultOutputContentError) MarshalJSON() ([]byte, error) {
+ errMsg := ""
+ if t.Error != nil {
+ errMsg = t.Error.Error()
+ }
+ dataBytes, err := json.Marshal(struct {
+ Error string `json:"error"`
+ }{
+ Error: errMsg,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(toolResultOutputJSON{
+ Type: string(ToolResultContentTypeError),
+ Data: json.RawMessage(dataBytes),
+ })
+}
+
+// UnmarshalJSON implements json.Unmarshaler for ToolResultOutputContentError.
+func (t *ToolResultOutputContentError) UnmarshalJSON(data []byte) error {
+ var tr toolResultOutputJSON
+ if err := json.Unmarshal(data, &tr); err != nil {
+ return err
+ }
+
+ var temp struct {
+ Error string `json:"error"`
+ }
+
+ if err := json.Unmarshal(tr.Data, &temp); err != nil {
+ return err
+ }
+ if temp.Error != "" {
+ t.Error = errors.New(temp.Error)
+ }
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler for ToolResultOutputContentMedia.
+func (t ToolResultOutputContentMedia) MarshalJSON() ([]byte, error) {
+ type alias ToolResultOutputContentMedia
+ dataBytes, err := json.Marshal(alias(t))
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(toolResultOutputJSON{
+ Type: string(ToolResultContentTypeMedia),
+ Data: json.RawMessage(dataBytes),
+ })
+}
+
+// UnmarshalJSON implements json.Unmarshaler for ToolResultOutputContentMedia.
+func (t *ToolResultOutputContentMedia) UnmarshalJSON(data []byte) error {
+ var tr toolResultOutputJSON
+ if err := json.Unmarshal(data, &tr); err != nil {
+ return err
+ }
+
+ type alias ToolResultOutputContentMedia
+ var temp alias
+
+ if err := json.Unmarshal(tr.Data, &temp); err != nil {
+ return err
+ }
+
+ *t = ToolResultOutputContentMedia(temp)
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler for TextPart.
+func (t TextPart) MarshalJSON() ([]byte, error) {
+ dataBytes, err := json.Marshal(struct {
+ Text string `json:"text"`
+ ProviderOptions ProviderOptions `json:"provider_options,omitempty"`
+ }{
+ Text: t.Text,
+ ProviderOptions: t.ProviderOptions,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(messagePartJSON{
+ Type: string(ContentTypeText),
+ Data: json.RawMessage(dataBytes),
+ })
+}
+
+// UnmarshalJSON implements json.Unmarshaler for TextPart.
+func (t *TextPart) UnmarshalJSON(data []byte) error {
+ var mpj messagePartJSON
+ if err := json.Unmarshal(data, &mpj); err != nil {
+ return err
+ }
+
+ var aux struct {
+ Text string `json:"text"`
+ ProviderOptions map[string]json.RawMessage `json:"provider_options,omitempty"`
+ }
+
+ if err := json.Unmarshal(mpj.Data, &aux); err != nil {
+ return err
+ }
+
+ t.Text = aux.Text
+
+ if len(aux.ProviderOptions) > 0 {
+ options, err := UnmarshalProviderOptions(aux.ProviderOptions)
+ if err != nil {
+ return err
+ }
+ t.ProviderOptions = options
+ }
+
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler for ReasoningPart.
+func (r ReasoningPart) MarshalJSON() ([]byte, error) {
+ dataBytes, err := json.Marshal(struct {
+ Text string `json:"text"`
+ ProviderOptions ProviderOptions `json:"provider_options,omitempty"`
+ }{
+ Text: r.Text,
+ ProviderOptions: r.ProviderOptions,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(messagePartJSON{
+ Type: string(ContentTypeReasoning),
+ Data: json.RawMessage(dataBytes),
+ })
+}
+
+// UnmarshalJSON implements json.Unmarshaler for ReasoningPart.
+func (r *ReasoningPart) UnmarshalJSON(data []byte) error {
+ var mpj messagePartJSON
+ if err := json.Unmarshal(data, &mpj); err != nil {
+ return err
+ }
+
+ var aux struct {
+ Text string `json:"text"`
+ ProviderOptions map[string]json.RawMessage `json:"provider_options,omitempty"`
+ }
+
+ if err := json.Unmarshal(mpj.Data, &aux); err != nil {
+ return err
+ }
+
+ r.Text = aux.Text
+
+ if len(aux.ProviderOptions) > 0 {
+ options, err := UnmarshalProviderOptions(aux.ProviderOptions)
+ if err != nil {
+ return err
+ }
+ r.ProviderOptions = options
+ }
+
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler for FilePart.
+func (f FilePart) MarshalJSON() ([]byte, error) {
+ dataBytes, err := json.Marshal(struct {
+ Filename string `json:"filename"`
+ Data []byte `json:"data"`
+ MediaType string `json:"media_type"`
+ ProviderOptions ProviderOptions `json:"provider_options,omitempty"`
+ }{
+ Filename: f.Filename,
+ Data: f.Data,
+ MediaType: f.MediaType,
+ ProviderOptions: f.ProviderOptions,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(messagePartJSON{
+ Type: string(ContentTypeFile),
+ Data: json.RawMessage(dataBytes),
+ })
+}
+
+// UnmarshalJSON implements json.Unmarshaler for FilePart.
+func (f *FilePart) UnmarshalJSON(data []byte) error {
+ var mpj messagePartJSON
+ if err := json.Unmarshal(data, &mpj); err != nil {
+ return err
+ }
+
+ var aux struct {
+ Filename string `json:"filename"`
+ Data []byte `json:"data"`
+ MediaType string `json:"media_type"`
+ ProviderOptions map[string]json.RawMessage `json:"provider_options,omitempty"`
+ }
+
+ if err := json.Unmarshal(mpj.Data, &aux); err != nil {
+ return err
+ }
+
+ f.Filename = aux.Filename
+ f.Data = aux.Data
+ f.MediaType = aux.MediaType
+
+ if len(aux.ProviderOptions) > 0 {
+ options, err := UnmarshalProviderOptions(aux.ProviderOptions)
+ if err != nil {
+ return err
+ }
+ f.ProviderOptions = options
+ }
+
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler for ToolCallPart.
+func (t ToolCallPart) MarshalJSON() ([]byte, error) {
+ dataBytes, err := json.Marshal(struct {
+ ToolCallID string `json:"tool_call_id"`
+ ToolName string `json:"tool_name"`
+ Input string `json:"input"`
+ ProviderExecuted bool `json:"provider_executed"`
+ ProviderOptions ProviderOptions `json:"provider_options,omitempty"`
+ }{
+ ToolCallID: t.ToolCallID,
+ ToolName: t.ToolName,
+ Input: t.Input,
+ ProviderExecuted: t.ProviderExecuted,
+ ProviderOptions: t.ProviderOptions,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(messagePartJSON{
+ Type: string(ContentTypeToolCall),
+ Data: json.RawMessage(dataBytes),
+ })
+}
+
+// UnmarshalJSON implements json.Unmarshaler for ToolCallPart.
+func (t *ToolCallPart) UnmarshalJSON(data []byte) error {
+ var mpj messagePartJSON
+ if err := json.Unmarshal(data, &mpj); err != nil {
+ return err
+ }
+
+ var aux struct {
+ ToolCallID string `json:"tool_call_id"`
+ ToolName string `json:"tool_name"`
+ Input string `json:"input"`
+ ProviderExecuted bool `json:"provider_executed"`
+ ProviderOptions map[string]json.RawMessage `json:"provider_options,omitempty"`
+ }
+
+ if err := json.Unmarshal(mpj.Data, &aux); err != nil {
+ return err
+ }
+
+ t.ToolCallID = aux.ToolCallID
+ t.ToolName = aux.ToolName
+ t.Input = aux.Input
+ t.ProviderExecuted = aux.ProviderExecuted
+
+ if len(aux.ProviderOptions) > 0 {
+ options, err := UnmarshalProviderOptions(aux.ProviderOptions)
+ if err != nil {
+ return err
+ }
+ t.ProviderOptions = options
+ }
+
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler for ToolResultPart.
+func (t ToolResultPart) MarshalJSON() ([]byte, error) {
+ dataBytes, err := json.Marshal(struct {
+ ToolCallID string `json:"tool_call_id"`
+ Output ToolResultOutputContent `json:"output"`
+ ProviderOptions ProviderOptions `json:"provider_options,omitempty"`
+ }{
+ ToolCallID: t.ToolCallID,
+ Output: t.Output,
+ ProviderOptions: t.ProviderOptions,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(messagePartJSON{
+ Type: string(ContentTypeToolResult),
+ Data: json.RawMessage(dataBytes),
+ })
+}
+
+// UnmarshalJSON implements json.Unmarshaler for ToolResultPart.
+func (t *ToolResultPart) UnmarshalJSON(data []byte) error {
+ var mpj messagePartJSON
+ if err := json.Unmarshal(data, &mpj); err != nil {
+ return err
+ }
+
+ var aux struct {
+ ToolCallID string `json:"tool_call_id"`
+ Output json.RawMessage `json:"output"`
+ ProviderOptions map[string]json.RawMessage `json:"provider_options,omitempty"`
+ }
+
+ if err := json.Unmarshal(mpj.Data, &aux); err != nil {
+ return err
+ }
+
+ t.ToolCallID = aux.ToolCallID
+
+ // Unmarshal the Output field
+ output, err := UnmarshalToolResultOutputContent(aux.Output)
+ if err != nil {
+ return fmt.Errorf("failed to unmarshal tool result output: %w", err)
+ }
+ t.Output = output
+
+ if len(aux.ProviderOptions) > 0 {
+ options, err := UnmarshalProviderOptions(aux.ProviderOptions)
+ if err != nil {
+ return err
+ }
+ t.ProviderOptions = options
+ }
+
+ return nil
+}
+
+// UnmarshalJSON implements json.Unmarshaler for Message.
+func (m *Message) UnmarshalJSON(data []byte) error {
+ var aux struct {
+ Role MessageRole `json:"role"`
+ Content []json.RawMessage `json:"content"`
+ ProviderOptions map[string]json.RawMessage `json:"provider_options"`
+ }
+
+ if err := json.Unmarshal(data, &aux); err != nil {
+ return err
+ }
+
+ m.Role = aux.Role
+
+ m.Content = make([]MessagePart, len(aux.Content))
+ for i, rawPart := range aux.Content {
+ part, err := UnmarshalMessagePart(rawPart)
+ if err != nil {
+ return fmt.Errorf("failed to unmarshal message part at index %d: %w", i, err)
+ }
+ m.Content[i] = part
+ }
+
+ if len(aux.ProviderOptions) > 0 {
+ options, err := UnmarshalProviderOptions(aux.ProviderOptions)
+ if err != nil {
+ return err
+ }
+ m.ProviderOptions = options
+ }
+
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler for FunctionTool.
+func (f FunctionTool) MarshalJSON() ([]byte, error) {
+ dataBytes, err := json.Marshal(struct {
+ Name string `json:"name"`
+ Description string `json:"description"`
+ InputSchema map[string]any `json:"input_schema"`
+ ProviderOptions ProviderOptions `json:"provider_options,omitempty"`
+ }{
+ Name: f.Name,
+ Description: f.Description,
+ InputSchema: f.InputSchema,
+ ProviderOptions: f.ProviderOptions,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(toolJSON{
+ Type: string(ToolTypeFunction),
+ Data: json.RawMessage(dataBytes),
+ })
+}
+
+// UnmarshalJSON implements json.Unmarshaler for FunctionTool.
+func (f *FunctionTool) UnmarshalJSON(data []byte) error {
+ var tj toolJSON
+ if err := json.Unmarshal(data, &tj); err != nil {
+ return err
+ }
+
+ var aux struct {
+ Name string `json:"name"`
+ Description string `json:"description"`
+ InputSchema map[string]any `json:"input_schema"`
+ ProviderOptions map[string]json.RawMessage `json:"provider_options,omitempty"`
+ }
+
+ if err := json.Unmarshal(tj.Data, &aux); err != nil {
+ return err
+ }
+
+ f.Name = aux.Name
+ f.Description = aux.Description
+ f.InputSchema = aux.InputSchema
+
+ if len(aux.ProviderOptions) > 0 {
+ options, err := UnmarshalProviderOptions(aux.ProviderOptions)
+ if err != nil {
+ return err
+ }
+ f.ProviderOptions = options
+ }
+
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler for ProviderDefinedTool.
+func (p ProviderDefinedTool) MarshalJSON() ([]byte, error) {
+ type alias ProviderDefinedTool
+ dataBytes, err := json.Marshal(alias(p))
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(toolJSON{
+ Type: string(ToolTypeProviderDefined),
+ Data: json.RawMessage(dataBytes),
+ })
+}
+
+// UnmarshalJSON implements json.Unmarshaler for ProviderDefinedTool.
+func (p *ProviderDefinedTool) UnmarshalJSON(data []byte) error {
+ var tj toolJSON
+ if err := json.Unmarshal(data, &tj); err != nil {
+ return err
+ }
+
+ type alias ProviderDefinedTool
+ var aux alias
+
+ if err := json.Unmarshal(tj.Data, &aux); err != nil {
+ return err
+ }
+
+ *p = ProviderDefinedTool(aux)
+
+ return nil
+}
+
+// UnmarshalTool unmarshals JSON into the appropriate Tool type.
+func UnmarshalTool(data []byte) (Tool, error) {
+ var tj toolJSON
+ if err := json.Unmarshal(data, &tj); err != nil {
+ return nil, err
+ }
+
+ switch ToolType(tj.Type) {
+ case ToolTypeFunction:
+ var tool FunctionTool
+ if err := tool.UnmarshalJSON(data); err != nil {
+ return nil, err
+ }
+ return tool, nil
+ case ToolTypeProviderDefined:
+ var tool ProviderDefinedTool
+ if err := tool.UnmarshalJSON(data); err != nil {
+ return nil, err
+ }
+ return tool, nil
+ default:
+ return nil, fmt.Errorf("unknown tool type: %s", tj.Type)
+ }
+}
+
+// UnmarshalContent unmarshals JSON into the appropriate Content type.
+func UnmarshalContent(data []byte) (Content, error) {
+ var cj contentJSON
+ if err := json.Unmarshal(data, &cj); err != nil {
+ return nil, err
+ }
+
+ switch ContentType(cj.Type) {
+ case ContentTypeText:
+ var content TextContent
+ if err := content.UnmarshalJSON(data); err != nil {
+ return nil, err
+ }
+ return content, nil
+ case ContentTypeReasoning:
+ var content ReasoningContent
+ if err := content.UnmarshalJSON(data); err != nil {
+ return nil, err
+ }
+ return content, nil
+ case ContentTypeFile:
+ var content FileContent
+ if err := content.UnmarshalJSON(data); err != nil {
+ return nil, err
+ }
+ return content, nil
+ case ContentTypeSource:
+ var content SourceContent
+ if err := content.UnmarshalJSON(data); err != nil {
+ return nil, err
+ }
+ return content, nil
+ case ContentTypeToolCall:
+ var content ToolCallContent
+ if err := content.UnmarshalJSON(data); err != nil {
+ return nil, err
+ }
+ return content, nil
+ case ContentTypeToolResult:
+ var content ToolResultContent
+ if err := content.UnmarshalJSON(data); err != nil {
+ return nil, err
+ }
+ return content, nil
+ default:
+ return nil, fmt.Errorf("unknown content type: %s", cj.Type)
+ }
+}
+
+// UnmarshalMessagePart unmarshals JSON into the appropriate MessagePart type.
+func UnmarshalMessagePart(data []byte) (MessagePart, error) {
+ var mpj messagePartJSON
+ if err := json.Unmarshal(data, &mpj); err != nil {
+ return nil, err
+ }
+
+ switch ContentType(mpj.Type) {
+ case ContentTypeText:
+ var part TextPart
+ if err := part.UnmarshalJSON(data); err != nil {
+ return nil, err
+ }
+ return part, nil
+ case ContentTypeReasoning:
+ var part ReasoningPart
+ if err := part.UnmarshalJSON(data); err != nil {
+ return nil, err
+ }
+ return part, nil
+ case ContentTypeFile:
+ var part FilePart
+ if err := part.UnmarshalJSON(data); err != nil {
+ return nil, err
+ }
+ return part, nil
+ case ContentTypeToolCall:
+ var part ToolCallPart
+ if err := part.UnmarshalJSON(data); err != nil {
+ return nil, err
+ }
+ return part, nil
+ case ContentTypeToolResult:
+ var part ToolResultPart
+ if err := part.UnmarshalJSON(data); err != nil {
+ return nil, err
+ }
+ return part, nil
+ default:
+ return nil, fmt.Errorf("unknown message part type: %s", mpj.Type)
+ }
+}
+
+// UnmarshalToolResultOutputContent unmarshals JSON into the appropriate ToolResultOutputContent type.
+func UnmarshalToolResultOutputContent(data []byte) (ToolResultOutputContent, error) {
+ var troj toolResultOutputJSON
+ if err := json.Unmarshal(data, &troj); err != nil {
+ return nil, err
+ }
+
+ switch ToolResultContentType(troj.Type) {
+ case ToolResultContentTypeText:
+ var content ToolResultOutputContentText
+ if err := content.UnmarshalJSON(data); err != nil {
+ return nil, err
+ }
+ return content, nil
+ case ToolResultContentTypeError:
+ var content ToolResultOutputContentError
+ if err := content.UnmarshalJSON(data); err != nil {
+ return nil, err
+ }
+ return content, nil
+ case ToolResultContentTypeMedia:
+ var content ToolResultOutputContentMedia
+ if err := content.UnmarshalJSON(data); err != nil {
+ return nil, err
+ }
+ return content, nil
+ default:
+ return nil, fmt.Errorf("unknown tool result output content type: %s", troj.Type)
+ }
+}
diff --git a/internal/fantasy/crush.json b/internal/fantasy/crush.json
new file mode 100644
index 000000000..f5daef89a
--- /dev/null
+++ b/internal/fantasy/crush.json
@@ -0,0 +1,6 @@
+{
+ "$schema": "https://charm.land/crush.json",
+ "lsp": {
+ "gopls": {}
+ }
+}
diff --git a/internal/fantasy/cspell.json b/internal/fantasy/cspell.json
new file mode 100644
index 000000000..8ca46c42b
--- /dev/null
+++ b/internal/fantasy/cspell.json
@@ -0,0 +1 @@
+{"flagWords":[],"words":["mapstructure","mapstructure","charmbracelet","providertests","joho","godotenv","stretchr","Quantizations","Logit","Probs","openrouter","openaisdk","Logprobs","Includable"],"version":"0.2","language":"en"}
\ No newline at end of file
diff --git a/internal/fantasy/doc.go b/internal/fantasy/doc.go
new file mode 100644
index 000000000..7d746c244
--- /dev/null
+++ b/internal/fantasy/doc.go
@@ -0,0 +1,2 @@
+// Package fantasy provides a unified interface for interacting with various AI language models.
+package fantasy
diff --git a/internal/fantasy/errors.go b/internal/fantasy/errors.go
new file mode 100644
index 000000000..0f9efaf98
--- /dev/null
+++ b/internal/fantasy/errors.go
@@ -0,0 +1,104 @@
+package fantasy
+
+import (
+ "errors"
+ "fmt"
+ "net/http"
+ "strings"
+
+ "github.com/charmbracelet/x/exp/slice"
+)
+
+// Error is a custom error type for the fantasy package.
+type Error struct {
+ Message string
+ Title string
+ Cause error
+}
+
+func (err *Error) Error() string {
+ if err.Title == "" {
+ return err.Message
+ }
+ return fmt.Sprintf("%s: %s", err.Title, err.Message)
+}
+
+func (err Error) Unwrap() error {
+ return err.Cause
+}
+
+// ProviderError represents an error returned by an external provider.
+type ProviderError struct {
+ Message string
+ Title string
+ Cause error
+
+ URL string
+ StatusCode int
+ RequestBody []byte
+ ResponseHeaders map[string]string
+ ResponseBody []byte
+}
+
+func (m *ProviderError) Error() string {
+ if m.Title == "" {
+ return m.Message
+ }
+ return fmt.Sprintf("%s: %s", m.Title, m.Message)
+}
+
+// IsRetryable checks if the error is retryable based on the status code.
+func (m *ProviderError) IsRetryable() bool {
+ return m.StatusCode == http.StatusRequestTimeout || m.StatusCode == http.StatusConflict || m.StatusCode == http.StatusTooManyRequests
+}
+
+// RetryError represents an error that occurred during retry operations.
+type RetryError struct {
+ Errors []error
+}
+
+func (e *RetryError) Error() string {
+ if err, ok := slice.Last(e.Errors); ok {
+ return fmt.Sprintf("retry error: %v", err)
+ }
+ return "retry error: no underlying errors"
+}
+
+func (e RetryError) Unwrap() error {
+ if err, ok := slice.Last(e.Errors); ok {
+ return err
+ }
+ return nil
+}
+
+// ErrorTitleForStatusCode returns a human-readable title for a given HTTP status code.
+func ErrorTitleForStatusCode(statusCode int) string {
+ return strings.ToLower(http.StatusText(statusCode))
+}
+
+// NoObjectGeneratedError is returned when object generation fails
+// due to parsing errors, validation errors, or model failures.
+type NoObjectGeneratedError struct {
+ RawText string
+ ParseError error
+ ValidationError error
+ Usage Usage
+ FinishReason FinishReason
+}
+
+// Error implements the error interface.
+func (e *NoObjectGeneratedError) Error() string {
+ if e.ValidationError != nil {
+ return fmt.Sprintf("object validation failed: %v", e.ValidationError)
+ }
+ if e.ParseError != nil {
+ return fmt.Sprintf("failed to parse object: %v", e.ParseError)
+ }
+ return "failed to generate object"
+}
+
+// IsNoObjectGeneratedError checks if an error is of type NoObjectGeneratedError.
+func IsNoObjectGeneratedError(err error) bool {
+ var target *NoObjectGeneratedError
+ return errors.As(err, &target)
+}
diff --git a/internal/fantasy/go.mod b/internal/fantasy/go.mod
new file mode 100644
index 000000000..5cff2f784
--- /dev/null
+++ b/internal/fantasy/go.mod
@@ -0,0 +1,81 @@
+module charm.land/fantasy
+
+go 1.25
+
+require (
+ charm.land/x/vcr v0.1.1
+ cloud.google.com/go/auth v0.18.1
+ github.com/aws/aws-sdk-go-v2 v1.41.1
+ github.com/aws/aws-sdk-go-v2/config v1.32.7
+ github.com/aws/smithy-go v1.24.0
+ github.com/charmbracelet/anthropic-sdk-go v0.0.0-20251024181547-21d6f3d9a904
+ github.com/charmbracelet/x/exp/slice v0.0.0-20250904123553-b4e2667e5ad5
+ github.com/charmbracelet/x/json v0.2.0
+ github.com/go-viper/mapstructure/v2 v2.5.0
+ github.com/google/uuid v1.6.0
+ github.com/joho/godotenv v1.5.1
+ github.com/kaptinlin/jsonschema v0.6.10
+ github.com/openai/openai-go/v2 v2.7.1
+ github.com/stretchr/testify v1.11.1
+ golang.org/x/oauth2 v0.35.0
+ google.golang.org/genai v1.45.0
+)
+
+require (
+ cloud.google.com/go v0.116.0 // indirect
+ cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
+ cloud.google.com/go/compute/metadata v0.9.0 // indirect
+ github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 // indirect
+ github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
+ github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 // indirect
+ github.com/aws/aws-sdk-go-v2/credentials v1.19.7 // indirect
+ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 // indirect
+ github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 // indirect
+ github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 // indirect
+ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13 // indirect
+ github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 // indirect
+ github.com/cespare/xxhash/v2 v2.3.0 // indirect
+ github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/felixge/httpsnoop v1.0.4 // indirect
+ github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e // indirect
+ github.com/go-logr/logr v1.4.3 // indirect
+ github.com/go-logr/stdr v1.2.2 // indirect
+ github.com/goccy/go-yaml v1.19.2 // indirect
+ github.com/google/go-cmp v0.7.0 // indirect
+ github.com/google/s2a-go v0.1.9 // indirect
+ github.com/googleapis/enterprise-certificate-proxy v0.3.7 // indirect
+ github.com/googleapis/gax-go/v2 v2.15.0 // indirect
+ github.com/gorilla/websocket v1.5.3 // indirect
+ github.com/kaptinlin/go-i18n v0.2.3 // indirect
+ github.com/kaptinlin/jsonpointer v0.4.9 // indirect
+ github.com/kaptinlin/messageformat-go v0.4.9 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
+ github.com/tidwall/gjson v1.18.0 // indirect
+ github.com/tidwall/match v1.1.1 // indirect
+ github.com/tidwall/pretty v1.2.1 // indirect
+ github.com/tidwall/sjson v1.2.5 // indirect
+ go.opentelemetry.io/auto/sdk v1.2.1 // indirect
+ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
+ go.opentelemetry.io/otel v1.39.0 // indirect
+ go.opentelemetry.io/otel/metric v1.39.0 // indirect
+ go.opentelemetry.io/otel/trace v1.39.0 // indirect
+ go.yaml.in/yaml/v4 v4.0.0-rc.3 // indirect
+ golang.org/x/crypto v0.45.0 // indirect
+ golang.org/x/net v0.47.0 // indirect
+ golang.org/x/sync v0.19.0 // indirect
+ golang.org/x/sys v0.39.0 // indirect
+ golang.org/x/text v0.33.0 // indirect
+ golang.org/x/time v0.14.0 // indirect
+ google.golang.org/api v0.239.0 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b // indirect
+ google.golang.org/grpc v1.76.0 // indirect
+ google.golang.org/protobuf v1.36.10 // indirect
+ gopkg.in/dnaeon/go-vcr.v4 v4.0.6-0.20251110073552-01de4eb40290 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+)
diff --git a/internal/fantasy/go.sum b/internal/fantasy/go.sum
new file mode 100644
index 000000000..973ca1b10
--- /dev/null
+++ b/internal/fantasy/go.sum
@@ -0,0 +1,185 @@
+charm.land/x/vcr v0.1.1 h1:PXCFMUG0rPtyk35rhfzYCJEduOzWXCIbrXTFq4OF/9Q=
+charm.land/x/vcr v0.1.1/go.mod h1:eByq2gqzWvcct/8XE2XO5KznoWEBiXH56+y2gphbltM=
+cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE=
+cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U=
+cloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs=
+cloud.google.com/go/auth v0.18.1/go.mod h1:GfTYoS9G3CWpRA3Va9doKN9mjPGRS+v41jmZAhBzbrA=
+cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
+cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
+cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
+cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
+github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU=
+github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
+github.com/aws/aws-sdk-go-v2 v1.41.1 h1:ABlyEARCDLN034NhxlRUSZr4l71mh+T5KAeGh6cerhU=
+github.com/aws/aws-sdk-go-v2 v1.41.1/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
+github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 h1:tW1/Rkad38LA15X4UQtjXZXNKsCgkshC3EbmcUmghTg=
+github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3/go.mod h1:UbnqO+zjqk3uIt9yCACHJ9IVNhyhOCnYk8yA19SAWrM=
+github.com/aws/aws-sdk-go-v2/config v1.32.7 h1:vxUyWGUwmkQ2g19n7JY/9YL8MfAIl7bTesIUykECXmY=
+github.com/aws/aws-sdk-go-v2/config v1.32.7/go.mod h1:2/Qm5vKUU/r7Y+zUk/Ptt2MDAEKAfUtKc1+3U1Mo3oY=
+github.com/aws/aws-sdk-go-v2/credentials v1.19.7 h1:tHK47VqqtJxOymRrNtUXN5SP/zUTvZKeLx4tH6PGQc8=
+github.com/aws/aws-sdk-go-v2/credentials v1.19.7/go.mod h1:qOZk8sPDrxhf+4Wf4oT2urYJrYt3RejHSzgAquYeppw=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 h1:I0GyV8wiYrP8XpA70g1HBcQO1JlQxCMTW9npl5UbDHY=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17/go.mod h1:tyw7BOl5bBe/oqvoIeECFJjMdzXoa/dfVz3QQ5lgHGA=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 h1:xOLELNKGp2vsiteLsvLPwxC+mYmO6OZ8PYgiuPJzF8U=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17/go.mod h1:5M5CI3D12dNOtH3/mk6minaRwI2/37ifCURZISxA/IQ=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 h1:WWLqlh79iO48yLkj1v3ISRNiv+3KdQoZ6JWyfcsyQik=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17/go.mod h1:EhG22vHRrvF8oXSTYStZhJc1aUgKtnJe+aOiFEV90cM=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 h1:RuNSMoozM8oXlgLG/n6WLaFGoea7/CddrCfIiSA+xdY=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17/go.mod h1:F2xxQ9TZz5gDWsclCtPQscGpP0VUOc8RqgFM3vDENmU=
+github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 h1:VrhDvQib/i0lxvr3zqlUwLwJP4fpmpyD9wYG1vfSu+Y=
+github.com/aws/aws-sdk-go-v2/service/signin v1.0.5/go.mod h1:k029+U8SY30/3/ras4G/Fnv/b88N4mAfliNn08Dem4M=
+github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 h1:v6EiMvhEYBoHABfbGB4alOYmCIrcgyPPiBE1wZAEbqk=
+github.com/aws/aws-sdk-go-v2/service/sso v1.30.9/go.mod h1:yifAsgBxgJWn3ggx70A3urX2AN49Y5sJTD1UQFlfqBw=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13 h1:gd84Omyu9JLriJVCbGApcLzVR3XtmC4ZDPcAI6Ftvds=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13/go.mod h1:sTGThjphYE4Ohw8vJiRStAcu3rbjtXRsdNB0TvZ5wwo=
+github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 h1:5fFjR/ToSOzB2OQ/XqWpZBmNvmP/pJ1jOWYlFDJTjRQ=
+github.com/aws/aws-sdk-go-v2/service/sts v1.41.6/go.mod h1:qgFDZQSD/Kys7nJnVqYlWKnh0SSdMjAi0uSwON4wgYQ=
+github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk=
+github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
+github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/charmbracelet/anthropic-sdk-go v0.0.0-20251024181547-21d6f3d9a904 h1:rwLdEpG9wE6kL69KkEKDiWprO8pQOZHZXeod6+9K+mw=
+github.com/charmbracelet/anthropic-sdk-go v0.0.0-20251024181547-21d6f3d9a904/go.mod h1:8TIYxZxsuCqqeJ0lga/b91tBwrbjoHDC66Sq5t8N2R4=
+github.com/charmbracelet/x/exp/slice v0.0.0-20250904123553-b4e2667e5ad5 h1:DTSZxdV9qQagD4iGcAt9RgaRBZtJl01bfKgdLzUzUPI=
+github.com/charmbracelet/x/exp/slice v0.0.0-20250904123553-b4e2667e5ad5/go.mod h1:vI5nDVMWi6veaYH+0Fmvpbe/+cv/iJfMntdh+N0+Tms=
+github.com/charmbracelet/x/json v0.2.0 h1:DqB+ZGx2h+Z+1s98HOuOyli+i97wsFQIxP2ZQANTPrQ=
+github.com/charmbracelet/x/json v0.2.0/go.mod h1:opFIflx2YgXgi49xVUu8gEQ21teFAxyMwvOiZhIvWNM=
+github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls=
+github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M=
+github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A=
+github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw=
+github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
+github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
+github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
+github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e h1:Lf/gRkoycfOBPa42vU2bbgPurFong6zXeFtPoxholzU=
+github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e/go.mod h1:uNVvRXArCGbZ508SxYYTC5v1JWoz2voff5pm25jU1Ok=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
+github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
+github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
+github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
+github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
+github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
+github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
+github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
+github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/googleapis/enterprise-certificate-proxy v0.3.7 h1:zrn2Ee/nWmHulBx5sAVrGgAa0f2/R35S4DJwfFaUPFQ=
+github.com/googleapis/enterprise-certificate-proxy v0.3.7/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
+github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=
+github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=
+github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
+github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
+github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
+github.com/kaptinlin/go-i18n v0.2.3 h1:jyN/YOXXLcnGRBLdU+a8+6782B97fWE5aQqAHtvvk8Q=
+github.com/kaptinlin/go-i18n v0.2.3/go.mod h1:O+Ax4HkMO0Jt4OaP4E4WCx0PAADeWkwk8Jgt9bjAU1w=
+github.com/kaptinlin/jsonpointer v0.4.9 h1:o//bYf4PCvnMJIIX8bIg77KB6DO3wBPAabRyPRKh680=
+github.com/kaptinlin/jsonpointer v0.4.9/go.mod h1:9y0LgXavlmVE5FSHShY5LRlURJJVhbyVJSRWkilrTqA=
+github.com/kaptinlin/jsonschema v0.6.10 h1:CYded7nrwVu7pU1GaIjtd9dSzgqZjh7+LTKFaWqS08I=
+github.com/kaptinlin/jsonschema v0.6.10/go.mod h1:ZXZ4K5KrRmCCF1i6dgvBsQifl+WTb8XShKj0NpQNrz8=
+github.com/kaptinlin/messageformat-go v0.4.9 h1:FR5j5n4aL4nG0afKn9vvANrKxLu7HjmbhJnw5ogIwAQ=
+github.com/kaptinlin/messageformat-go v0.4.9/go.mod h1:qZzrGrlvWDz2KyyvN3dOWcK9PVSRV1BnfnNU+zB/RWc=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
+github.com/openai/openai-go/v2 v2.7.1 h1:/tfvTJhfv7hTSL8mWwc5VL4WLLSDL5yn9VqVykdu9r8=
+github.com/openai/openai-go/v2 v2.7.1/go.mod h1:jrJs23apqJKKbT+pqtFgNKpRju/KP9zpUTZhz3GElQE=
+github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
+github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
+github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
+github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
+github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
+github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
+github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
+github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
+github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
+github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
+github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
+github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
+github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
+github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
+github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
+github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
+github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
+github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
+go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
+go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
+go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
+go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
+go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
+go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
+go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
+go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
+go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
+go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
+go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
+go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
+go.yaml.in/yaml/v4 v4.0.0-rc.3 h1:3h1fjsh1CTAPjW7q/EMe+C8shx5d8ctzZTrLcs/j8Go=
+go.yaml.in/yaml/v4 v4.0.0-rc.3/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0=
+golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
+golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
+golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
+golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
+golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=
+golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
+golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
+golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
+golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
+golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
+golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
+golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
+golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
+gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
+gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
+google.golang.org/api v0.239.0 h1:2hZKUnFZEy81eugPs4e2XzIJ5SOwQg0G82bpXD65Puo=
+google.golang.org/api v0.239.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50=
+google.golang.org/genai v1.45.0 h1:s80ZpS42XW0zu/ogiOtenCio17nJ7reEFJjoCftukpA=
+google.golang.org/genai v1.45.0/go.mod h1:A3kkl0nyBjyFlNjgxIwKq70julKbIxpSxqKO5gw/gmk=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b h1:zPKJod4w6F1+nRGDI9ubnXYhU9NSWoFAijkHkUXeTK8=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
+google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
+google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
+google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
+google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/dnaeon/go-vcr.v4 v4.0.6-0.20251110073552-01de4eb40290 h1:g3ah7zaWmw41EtOgBNXpx8zk4HYuH3OMwB+qh1Dt834=
+gopkg.in/dnaeon/go-vcr.v4 v4.0.6-0.20251110073552-01de4eb40290/go.mod h1:sbq5oMEcM4PXngbcNbHhzfCP9OdZodLhrbRYoyg09HY=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/internal/fantasy/json_test.go b/internal/fantasy/json_test.go
new file mode 100644
index 000000000..b1088434a
--- /dev/null
+++ b/internal/fantasy/json_test.go
@@ -0,0 +1,752 @@
+package fantasy
+
+import (
+ "encoding/json"
+ "errors"
+ "reflect"
+ "testing"
+)
+
+func TestMessageJSONSerialization(t *testing.T) {
+ tests := []struct {
+ name string
+ message Message
+ }{
+ {
+ name: "simple text message",
+ message: Message{
+ Role: MessageRoleUser,
+ Content: []MessagePart{
+ TextPart{Text: "Hello, world!"},
+ },
+ },
+ },
+ {
+ name: "message with multiple text parts",
+ message: Message{
+ Role: MessageRoleAssistant,
+ Content: []MessagePart{
+ TextPart{Text: "First part"},
+ TextPart{Text: "Second part"},
+ TextPart{Text: "Third part"},
+ },
+ },
+ },
+ {
+ name: "message with reasoning part",
+ message: Message{
+ Role: MessageRoleAssistant,
+ Content: []MessagePart{
+ ReasoningPart{Text: "Let me think about this..."},
+ TextPart{Text: "Here's my answer"},
+ },
+ },
+ },
+ {
+ name: "message with file part",
+ message: Message{
+ Role: MessageRoleUser,
+ Content: []MessagePart{
+ TextPart{Text: "Here's an image:"},
+ FilePart{
+ Filename: "test.png",
+ Data: []byte{0x89, 0x50, 0x4E, 0x47}, // PNG header
+ MediaType: "image/png",
+ },
+ },
+ },
+ },
+ {
+ name: "message with tool call",
+ message: Message{
+ Role: MessageRoleAssistant,
+ Content: []MessagePart{
+ ToolCallPart{
+ ToolCallID: "call_123",
+ ToolName: "get_weather",
+ Input: `{"location": "San Francisco"}`,
+ ProviderExecuted: false,
+ },
+ },
+ },
+ },
+ {
+ name: "message with tool result - text output",
+ message: Message{
+ Role: MessageRoleTool,
+ Content: []MessagePart{
+ ToolResultPart{
+ ToolCallID: "call_123",
+ Output: ToolResultOutputContentText{
+ Text: "The weather is sunny, 72°F",
+ },
+ },
+ },
+ },
+ },
+ {
+ name: "message with tool result - error output",
+ message: Message{
+ Role: MessageRoleTool,
+ Content: []MessagePart{
+ ToolResultPart{
+ ToolCallID: "call_456",
+ Output: ToolResultOutputContentError{
+ Error: errors.New("API rate limit exceeded"),
+ },
+ },
+ },
+ },
+ },
+ {
+ name: "message with tool result - media output",
+ message: Message{
+ Role: MessageRoleTool,
+ Content: []MessagePart{
+ ToolResultPart{
+ ToolCallID: "call_789",
+ Output: ToolResultOutputContentMedia{
+ Data: "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",
+ MediaType: "image/png",
+ },
+ },
+ },
+ },
+ },
+ {
+ name: "complex message with mixed content",
+ message: Message{
+ Role: MessageRoleAssistant,
+ Content: []MessagePart{
+ TextPart{Text: "I'll analyze this image and call some tools."},
+ ReasoningPart{Text: "First, I need to identify the objects..."},
+ ToolCallPart{
+ ToolCallID: "call_001",
+ ToolName: "analyze_image",
+ Input: `{"image_id": "img_123"}`,
+ ProviderExecuted: false,
+ },
+ ToolCallPart{
+ ToolCallID: "call_002",
+ ToolName: "get_context",
+ Input: `{"query": "similar images"}`,
+ ProviderExecuted: true,
+ },
+ },
+ },
+ },
+ {
+ name: "system message",
+ message: Message{
+ Role: MessageRoleSystem,
+ Content: []MessagePart{
+ TextPart{Text: "You are a helpful assistant."},
+ },
+ },
+ },
+ {
+ name: "empty content",
+ message: Message{
+ Role: MessageRoleUser,
+ Content: []MessagePart{},
+ },
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ // Marshal the message
+ data, err := json.Marshal(tt.message)
+ if err != nil {
+ t.Fatalf("failed to marshal message: %v", err)
+ }
+
+ // Unmarshal back
+ var decoded Message
+ err = json.Unmarshal(data, &decoded)
+ if err != nil {
+ t.Fatalf("failed to unmarshal message: %v", err)
+ }
+
+ // Compare roles
+ if decoded.Role != tt.message.Role {
+ t.Errorf("role mismatch: got %v, want %v", decoded.Role, tt.message.Role)
+ }
+
+ // Compare content length
+ if len(decoded.Content) != len(tt.message.Content) {
+ t.Fatalf("content length mismatch: got %d, want %d", len(decoded.Content), len(tt.message.Content))
+ }
+
+ // Compare each content part
+ for i := range tt.message.Content {
+ original := tt.message.Content[i]
+ decodedPart := decoded.Content[i]
+
+ if original.GetType() != decodedPart.GetType() {
+ t.Errorf("content[%d] type mismatch: got %v, want %v", i, decodedPart.GetType(), original.GetType())
+ continue
+ }
+
+ compareMessagePart(t, i, original, decodedPart)
+ }
+ })
+ }
+}
+
+func compareMessagePart(t *testing.T, index int, original, decoded MessagePart) {
+ switch original.GetType() {
+ case ContentTypeText:
+ orig := original.(TextPart)
+ dec := decoded.(TextPart)
+ if orig.Text != dec.Text {
+ t.Errorf("content[%d] text mismatch: got %q, want %q", index, dec.Text, orig.Text)
+ }
+
+ case ContentTypeReasoning:
+ orig := original.(ReasoningPart)
+ dec := decoded.(ReasoningPart)
+ if orig.Text != dec.Text {
+ t.Errorf("content[%d] reasoning text mismatch: got %q, want %q", index, dec.Text, orig.Text)
+ }
+
+ case ContentTypeFile:
+ orig := original.(FilePart)
+ dec := decoded.(FilePart)
+ if orig.Filename != dec.Filename {
+ t.Errorf("content[%d] filename mismatch: got %q, want %q", index, dec.Filename, orig.Filename)
+ }
+ if orig.MediaType != dec.MediaType {
+ t.Errorf("content[%d] media type mismatch: got %q, want %q", index, dec.MediaType, orig.MediaType)
+ }
+ if !reflect.DeepEqual(orig.Data, dec.Data) {
+ t.Errorf("content[%d] file data mismatch", index)
+ }
+
+ case ContentTypeToolCall:
+ orig := original.(ToolCallPart)
+ dec := decoded.(ToolCallPart)
+ if orig.ToolCallID != dec.ToolCallID {
+ t.Errorf("content[%d] tool call id mismatch: got %q, want %q", index, dec.ToolCallID, orig.ToolCallID)
+ }
+ if orig.ToolName != dec.ToolName {
+ t.Errorf("content[%d] tool name mismatch: got %q, want %q", index, dec.ToolName, orig.ToolName)
+ }
+ if orig.Input != dec.Input {
+ t.Errorf("content[%d] tool input mismatch: got %q, want %q", index, dec.Input, orig.Input)
+ }
+ if orig.ProviderExecuted != dec.ProviderExecuted {
+ t.Errorf("content[%d] provider executed mismatch: got %v, want %v", index, dec.ProviderExecuted, orig.ProviderExecuted)
+ }
+
+ case ContentTypeToolResult:
+ orig := original.(ToolResultPart)
+ dec := decoded.(ToolResultPart)
+ if orig.ToolCallID != dec.ToolCallID {
+ t.Errorf("content[%d] tool result call id mismatch: got %q, want %q", index, dec.ToolCallID, orig.ToolCallID)
+ }
+ compareToolResultOutput(t, index, orig.Output, dec.Output)
+ }
+}
+
+func compareToolResultOutput(t *testing.T, index int, original, decoded ToolResultOutputContent) {
+ if original.GetType() != decoded.GetType() {
+ t.Errorf("content[%d] tool result output type mismatch: got %v, want %v", index, decoded.GetType(), original.GetType())
+ return
+ }
+
+ switch original.GetType() {
+ case ToolResultContentTypeText:
+ orig := original.(ToolResultOutputContentText)
+ dec := decoded.(ToolResultOutputContentText)
+ if orig.Text != dec.Text {
+ t.Errorf("content[%d] tool result text mismatch: got %q, want %q", index, dec.Text, orig.Text)
+ }
+
+ case ToolResultContentTypeError:
+ orig := original.(ToolResultOutputContentError)
+ dec := decoded.(ToolResultOutputContentError)
+ if orig.Error.Error() != dec.Error.Error() {
+ t.Errorf("content[%d] tool result error mismatch: got %q, want %q", index, dec.Error.Error(), orig.Error.Error())
+ }
+
+ case ToolResultContentTypeMedia:
+ orig := original.(ToolResultOutputContentMedia)
+ dec := decoded.(ToolResultOutputContentMedia)
+ if orig.Data != dec.Data {
+ t.Errorf("content[%d] tool result media data mismatch", index)
+ }
+ if orig.MediaType != dec.MediaType {
+ t.Errorf("content[%d] tool result media type mismatch: got %q, want %q", index, dec.MediaType, orig.MediaType)
+ }
+ }
+}
+
+func TestHelperFunctions(t *testing.T) {
+ t.Run("NewUserMessage - text only", func(t *testing.T) {
+ msg := NewUserMessage("Hello")
+
+ data, err := json.Marshal(msg)
+ if err != nil {
+ t.Fatalf("failed to marshal: %v", err)
+ }
+
+ var decoded Message
+ if err := json.Unmarshal(data, &decoded); err != nil {
+ t.Fatalf("failed to unmarshal: %v", err)
+ }
+
+ if decoded.Role != MessageRoleUser {
+ t.Errorf("role mismatch: got %v, want %v", decoded.Role, MessageRoleUser)
+ }
+
+ if len(decoded.Content) != 1 {
+ t.Fatalf("expected 1 content part, got %d", len(decoded.Content))
+ }
+
+ textPart := decoded.Content[0].(TextPart)
+ if textPart.Text != "Hello" {
+ t.Errorf("text mismatch: got %q, want %q", textPart.Text, "Hello")
+ }
+ })
+
+ t.Run("NewUserMessage - with files", func(t *testing.T) {
+ msg := NewUserMessage("Check this image",
+ FilePart{
+ Filename: "image1.jpg",
+ Data: []byte{0xFF, 0xD8, 0xFF},
+ MediaType: "image/jpeg",
+ },
+ FilePart{
+ Filename: "image2.png",
+ Data: []byte{0x89, 0x50, 0x4E, 0x47},
+ MediaType: "image/png",
+ },
+ )
+
+ data, err := json.Marshal(msg)
+ if err != nil {
+ t.Fatalf("failed to marshal: %v", err)
+ }
+
+ var decoded Message
+ if err := json.Unmarshal(data, &decoded); err != nil {
+ t.Fatalf("failed to unmarshal: %v", err)
+ }
+
+ if len(decoded.Content) != 3 {
+ t.Fatalf("expected 3 content parts, got %d", len(decoded.Content))
+ }
+
+ // Check text part
+ textPart := decoded.Content[0].(TextPart)
+ if textPart.Text != "Check this image" {
+ t.Errorf("text mismatch: got %q, want %q", textPart.Text, "Check this image")
+ }
+
+ // Check first file
+ file1 := decoded.Content[1].(FilePart)
+ if file1.Filename != "image1.jpg" {
+ t.Errorf("file1 name mismatch: got %q, want %q", file1.Filename, "image1.jpg")
+ }
+
+ // Check second file
+ file2 := decoded.Content[2].(FilePart)
+ if file2.Filename != "image2.png" {
+ t.Errorf("file2 name mismatch: got %q, want %q", file2.Filename, "image2.png")
+ }
+ })
+
+ t.Run("NewSystemMessage - single prompt", func(t *testing.T) {
+ msg := NewSystemMessage("You are a helpful assistant.")
+
+ data, err := json.Marshal(msg)
+ if err != nil {
+ t.Fatalf("failed to marshal: %v", err)
+ }
+
+ var decoded Message
+ if err := json.Unmarshal(data, &decoded); err != nil {
+ t.Fatalf("failed to unmarshal: %v", err)
+ }
+
+ if decoded.Role != MessageRoleSystem {
+ t.Errorf("role mismatch: got %v, want %v", decoded.Role, MessageRoleSystem)
+ }
+
+ if len(decoded.Content) != 1 {
+ t.Fatalf("expected 1 content part, got %d", len(decoded.Content))
+ }
+
+ textPart := decoded.Content[0].(TextPart)
+ if textPart.Text != "You are a helpful assistant." {
+ t.Errorf("text mismatch: got %q, want %q", textPart.Text, "You are a helpful assistant.")
+ }
+ })
+
+ t.Run("NewSystemMessage - multiple prompts", func(t *testing.T) {
+ msg := NewSystemMessage("First instruction", "Second instruction", "Third instruction")
+
+ data, err := json.Marshal(msg)
+ if err != nil {
+ t.Fatalf("failed to marshal: %v", err)
+ }
+
+ var decoded Message
+ if err := json.Unmarshal(data, &decoded); err != nil {
+ t.Fatalf("failed to unmarshal: %v", err)
+ }
+
+ if len(decoded.Content) != 3 {
+ t.Fatalf("expected 3 content parts, got %d", len(decoded.Content))
+ }
+
+ expected := []string{"First instruction", "Second instruction", "Third instruction"}
+ for i, exp := range expected {
+ textPart := decoded.Content[i].(TextPart)
+ if textPart.Text != exp {
+ t.Errorf("content[%d] text mismatch: got %q, want %q", i, textPart.Text, exp)
+ }
+ }
+ })
+}
+
+func TestEdgeCases(t *testing.T) {
+ t.Run("empty text part", func(t *testing.T) {
+ msg := Message{
+ Role: MessageRoleUser,
+ Content: []MessagePart{
+ TextPart{Text: ""},
+ },
+ }
+
+ data, err := json.Marshal(msg)
+ if err != nil {
+ t.Fatalf("failed to marshal: %v", err)
+ }
+
+ var decoded Message
+ if err := json.Unmarshal(data, &decoded); err != nil {
+ t.Fatalf("failed to unmarshal: %v", err)
+ }
+
+ textPart := decoded.Content[0].(TextPart)
+ if textPart.Text != "" {
+ t.Errorf("expected empty text, got %q", textPart.Text)
+ }
+ })
+
+ t.Run("nil error in tool result", func(t *testing.T) {
+ msg := Message{
+ Role: MessageRoleTool,
+ Content: []MessagePart{
+ ToolResultPart{
+ ToolCallID: "call_123",
+ Output: ToolResultOutputContentError{
+ Error: nil,
+ },
+ },
+ },
+ }
+
+ data, err := json.Marshal(msg)
+ if err != nil {
+ t.Fatalf("failed to marshal: %v", err)
+ }
+
+ var decoded Message
+ if err := json.Unmarshal(data, &decoded); err != nil {
+ t.Fatalf("failed to unmarshal: %v", err)
+ }
+
+ toolResult := decoded.Content[0].(ToolResultPart)
+ errorOutput := toolResult.Output.(ToolResultOutputContentError)
+ if errorOutput.Error != nil {
+ t.Errorf("expected nil error, got %v", errorOutput.Error)
+ }
+ })
+
+ t.Run("empty file data", func(t *testing.T) {
+ msg := Message{
+ Role: MessageRoleUser,
+ Content: []MessagePart{
+ FilePart{
+ Filename: "empty.txt",
+ Data: []byte{},
+ MediaType: "text/plain",
+ },
+ },
+ }
+
+ data, err := json.Marshal(msg)
+ if err != nil {
+ t.Fatalf("failed to marshal: %v", err)
+ }
+
+ var decoded Message
+ if err := json.Unmarshal(data, &decoded); err != nil {
+ t.Fatalf("failed to unmarshal: %v", err)
+ }
+
+ filePart := decoded.Content[0].(FilePart)
+ if len(filePart.Data) != 0 {
+ t.Errorf("expected empty data, got %d bytes", len(filePart.Data))
+ }
+ })
+
+ t.Run("unicode in text", func(t *testing.T) {
+ msg := Message{
+ Role: MessageRoleUser,
+ Content: []MessagePart{
+ TextPart{Text: "Hello äøē! š ŠŃивеŃ"},
+ },
+ }
+
+ data, err := json.Marshal(msg)
+ if err != nil {
+ t.Fatalf("failed to marshal: %v", err)
+ }
+
+ var decoded Message
+ if err := json.Unmarshal(data, &decoded); err != nil {
+ t.Fatalf("failed to unmarshal: %v", err)
+ }
+
+ textPart := decoded.Content[0].(TextPart)
+ if textPart.Text != "Hello äøē! š ŠŃивеŃ" {
+ t.Errorf("unicode text mismatch: got %q, want %q", textPart.Text, "Hello äøē! š ŠŃивеŃ")
+ }
+ })
+}
+
+func TestInvalidJSONHandling(t *testing.T) {
+ t.Run("unknown message part type", func(t *testing.T) {
+ invalidJSON := `{
+ "role": "user",
+ "content": [
+ {
+ "type": "unknown-type",
+ "data": {}
+ }
+ ],
+ "provider_options": null
+ }`
+
+ var msg Message
+ err := json.Unmarshal([]byte(invalidJSON), &msg)
+ if err == nil {
+ t.Error("expected error for unknown message part type, got nil")
+ }
+ })
+
+ t.Run("unknown tool result output type", func(t *testing.T) {
+ invalidJSON := `{
+ "role": "tool",
+ "content": [
+ {
+ "type": "tool-result",
+ "data": {
+ "tool_call_id": "call_123",
+ "output": {
+ "type": "unknown-output-type",
+ "data": {}
+ },
+ "provider_options": null
+ }
+ }
+ ],
+ "provider_options": null
+ }`
+
+ var msg Message
+ err := json.Unmarshal([]byte(invalidJSON), &msg)
+ if err == nil {
+ t.Error("expected error for unknown tool result output type, got nil")
+ }
+ })
+
+ t.Run("malformed JSON", func(t *testing.T) {
+ invalidJSON := `{"role": "user", "content": [`
+
+ var msg Message
+ err := json.Unmarshal([]byte(invalidJSON), &msg)
+ if err == nil {
+ t.Error("expected error for malformed JSON, got nil")
+ }
+ })
+}
+
+// Mock provider data for testing provider options
+type mockProviderData struct {
+ Key string `json:"key"`
+}
+
+func (m mockProviderData) Options() {}
+func (m mockProviderData) Type() string { return "mock" }
+func (m mockProviderData) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string `json:"type"`
+ mockProviderData
+ }{
+ Type: "mock",
+ mockProviderData: m,
+ })
+}
+
+func (m *mockProviderData) UnmarshalJSON(data []byte) error {
+ var aux struct {
+ Type string `json:"type"`
+ mockProviderData
+ }
+ if err := json.Unmarshal(data, &aux); err != nil {
+ return err
+ }
+ *m = aux.mockProviderData
+ return nil
+}
+
+func TestPromptSerialization(t *testing.T) {
+ t.Run("serialize prompt (message slice)", func(t *testing.T) {
+ prompt := Prompt{
+ NewSystemMessage("You are helpful"),
+ NewUserMessage("Hello"),
+ Message{
+ Role: MessageRoleAssistant,
+ Content: []MessagePart{
+ TextPart{Text: "Hi there!"},
+ },
+ },
+ }
+
+ data, err := json.Marshal(prompt)
+ if err != nil {
+ t.Fatalf("failed to marshal prompt: %v", err)
+ }
+
+ var decoded Prompt
+ if err := json.Unmarshal(data, &decoded); err != nil {
+ t.Fatalf("failed to unmarshal prompt: %v", err)
+ }
+
+ if len(decoded) != 3 {
+ t.Fatalf("expected 3 messages, got %d", len(decoded))
+ }
+
+ if decoded[0].Role != MessageRoleSystem {
+ t.Errorf("message 0 role mismatch: got %v, want %v", decoded[0].Role, MessageRoleSystem)
+ }
+
+ if decoded[1].Role != MessageRoleUser {
+ t.Errorf("message 1 role mismatch: got %v, want %v", decoded[1].Role, MessageRoleUser)
+ }
+
+ if decoded[2].Role != MessageRoleAssistant {
+ t.Errorf("message 2 role mismatch: got %v, want %v", decoded[2].Role, MessageRoleAssistant)
+ }
+ })
+}
+
+func TestStreamPartErrorSerialization(t *testing.T) {
+ t.Run("stream part with ProviderError containing OpenAI API error", func(t *testing.T) {
+ // Create a mock OpenAI API error
+ openaiErr := errors.New("invalid_api_key: Incorrect API key provided")
+
+ // Wrap in ProviderError
+ providerErr := &ProviderError{
+ Title: "unauthorized",
+ Message: "Incorrect API key provided",
+ Cause: openaiErr,
+ URL: "https://api.openai.com/v1/chat/completions",
+ StatusCode: 401,
+ RequestBody: []byte(`{"model":"gpt-4","messages":[]}`),
+ ResponseHeaders: map[string]string{
+ "content-type": "application/json",
+ },
+ ResponseBody: []byte(`{"error":{"message":"Incorrect API key provided","type":"invalid_request_error"}}`),
+ }
+
+ // Create StreamPart with error
+ streamPart := StreamPart{
+ Type: StreamPartTypeError,
+ Error: providerErr,
+ }
+
+ // Marshal the stream part
+ data, err := json.Marshal(streamPart)
+ if err != nil {
+ t.Fatalf("failed to marshal stream part: %v", err)
+ }
+
+ // Unmarshal back
+ var decoded StreamPart
+ err = json.Unmarshal(data, &decoded)
+ if err != nil {
+ t.Fatalf("failed to unmarshal stream part: %v", err)
+ }
+
+ // Verify the stream part type
+ if decoded.Type != StreamPartTypeError {
+ t.Errorf("type mismatch: got %v, want %v", decoded.Type, StreamPartTypeError)
+ }
+
+ // Verify error exists
+ if decoded.Error == nil {
+ t.Fatal("expected error to be present, got nil")
+ }
+
+ // Verify error message
+ expectedMsg := "unauthorized: Incorrect API key provided"
+ if decoded.Error.Error() != expectedMsg {
+ t.Errorf("error message mismatch: got %q, want %q", decoded.Error.Error(), expectedMsg)
+ }
+ })
+
+ t.Run("unmarshal stream part with error from JSON", func(t *testing.T) {
+ // JSON representing a StreamPart with an error
+ jsonData := `{
+ "type": "error",
+ "error": "unauthorized: Incorrect API key provided",
+ "id": "",
+ "tool_call_name": "",
+ "tool_call_input": "",
+ "delta": "",
+ "provider_executed": false,
+ "usage": {
+ "input_tokens": 0,
+ "output_tokens": 0,
+ "total_tokens": 0,
+ "reasoning_tokens": 0,
+ "cache_creation_tokens": 0,
+ "cache_read_tokens": 0
+ },
+ "finish_reason": "",
+ "warnings": null,
+ "source_type": "",
+ "url": "",
+ "title": "",
+ "provider_metadata": null
+ }`
+
+ var streamPart StreamPart
+ err := json.Unmarshal([]byte(jsonData), &streamPart)
+ if err != nil {
+ t.Fatalf("failed to unmarshal stream part: %v", err)
+ }
+
+ // Verify the stream part type
+ if streamPart.Type != StreamPartTypeError {
+ t.Errorf("type mismatch: got %v, want %v", streamPart.Type, StreamPartTypeError)
+ }
+
+ // Verify error exists
+ if streamPart.Error == nil {
+ t.Fatal("expected error to be present, got nil")
+ }
+
+ // Verify error message
+ expectedMsg := "unauthorized: Incorrect API key provided"
+ if streamPart.Error.Error() != expectedMsg {
+ t.Errorf("error message mismatch: got %q, want %q", streamPart.Error.Error(), expectedMsg)
+ }
+ })
+}
diff --git a/internal/fantasy/jsonrepair/jsonrepair.go b/internal/fantasy/jsonrepair/jsonrepair.go
new file mode 100644
index 000000000..26aa5b98a
--- /dev/null
+++ b/internal/fantasy/jsonrepair/jsonrepair.go
@@ -0,0 +1,1648 @@
+// Package jsonrepair provides utilities to repair malformed JSON.
+package jsonrepair
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "reflect"
+ "slices"
+ "strconv"
+ "strings"
+ "unicode"
+ "unicode/utf16"
+)
+
+// Option is a function that configures the JSON repairer.
+type Option func(*options)
+
+type options struct {
+ ensureASCII *bool
+ skipJSONLoads bool
+ streamStable bool
+ strict bool
+}
+
+// LogEntry represents a log entry with context and text.
+type LogEntry struct {
+ Context string `json:"context"`
+ Text string `json:"text"`
+}
+
+type numberValue struct {
+ raw string
+}
+
+type objectEntry struct {
+ key string
+ value any
+}
+
+type orderedObject struct {
+ entries []objectEntry
+ index map[string]int
+}
+
+func newOrderedObject() *orderedObject {
+ return &orderedObject{index: map[string]int{}}
+}
+
+func (o *orderedObject) set(key string, value any) {
+ if idx, ok := o.index[key]; ok {
+ o.entries[idx].value = value
+ return
+ }
+ o.index[key] = len(o.entries)
+ o.entries = append(o.entries, objectEntry{key: key, value: value})
+}
+
+func (o *orderedObject) get(key string) (any, bool) {
+ idx, ok := o.index[key]
+ if !ok {
+ return nil, false
+ }
+ return o.entries[idx].value, true
+}
+
+func (o *orderedObject) lastKey() (string, bool) {
+ if len(o.entries) == 0 {
+ return "", false
+ }
+ return o.entries[len(o.entries)-1].key, true
+}
+
+func (o *orderedObject) hasKey(key string) bool {
+ _, ok := o.index[key]
+ return ok
+}
+
+func (o *orderedObject) merge(other *orderedObject) {
+ for _, entry := range other.entries {
+ o.set(entry.key, entry.value)
+ }
+}
+
+type contextValue int
+
+const (
+ contextObjectKey contextValue = iota
+ contextObjectValue
+ contextArray
+)
+
+type jsonContext struct {
+ context []contextValue
+ current *contextValue
+ empty bool
+}
+
+func newJSONContext() *jsonContext {
+ return &jsonContext{empty: true}
+}
+
+func (c *jsonContext) set(value contextValue) {
+ c.context = append(c.context, value)
+ c.current = &c.context[len(c.context)-1]
+ c.empty = false
+}
+
+func (c *jsonContext) reset() {
+ if len(c.context) > 0 {
+ c.context = c.context[:len(c.context)-1]
+ }
+ if len(c.context) == 0 {
+ c.current = nil
+ c.empty = true
+ return
+ }
+ c.current = &c.context[len(c.context)-1]
+}
+
+func (c *jsonContext) contains(value contextValue) bool {
+ return slices.Contains(c.context, value)
+}
+
+type parser struct {
+ jsonStr []rune
+ index int
+ context *jsonContext
+ logging bool
+ logger []LogEntry
+ streamStable bool
+ strict bool
+ log func(string)
+}
+
+func newParser(input string, logging bool, streamStable bool, strict bool) *parser {
+ p := &parser{
+ jsonStr: []rune(input),
+ context: newJSONContext(),
+ logging: logging,
+ streamStable: streamStable,
+ strict: strict,
+ }
+ if logging {
+ p.log = p.addLog
+ } else {
+ p.log = func(string) {}
+ }
+ return p
+}
+
+func (p *parser) addLog(text string) {
+ window := 10
+ start := max(p.index-window, 0)
+ end := min(p.index+window, len(p.jsonStr))
+ context := string(p.jsonStr[start:end])
+ p.logger = append(p.logger, LogEntry{Text: text, Context: context})
+}
+
+func (p *parser) parse() (any, []LogEntry, error) {
+ jsonValue, err := p.parseJSON()
+ if err != nil {
+ return nil, nil, err
+ }
+ if p.index < len(p.jsonStr) {
+ p.log("The parser returned early, checking if there's more json elements")
+ values := []any{jsonValue}
+ for p.index < len(p.jsonStr) {
+ p.context.reset()
+ j, parseErr := p.parseJSON()
+ if parseErr != nil {
+ return nil, nil, parseErr
+ }
+ if isTruthy(j) {
+ if len(values) > 0 && isSameObject(values[len(values)-1], j) {
+ values = values[:len(values)-1]
+ } else if len(values) > 0 && !isTruthy(values[len(values)-1]) {
+ values = values[:len(values)-1]
+ }
+ values = append(values, j)
+ } else {
+ if len(values) > 1 {
+ _, ok := p.getCharAt(0)
+ if !ok {
+ break
+ }
+ if len(values) > 1 {
+ values = values[:len(values)-1]
+ }
+ p.index = len(p.jsonStr)
+ break
+ }
+ p.index++
+ }
+ }
+ if len(values) == 1 {
+ p.log("There were no more elements, returning the element without the array")
+ jsonValue = values[0]
+ } else if p.strict {
+ p.log("Multiple top-level JSON elements found in strict mode, raising an error")
+ return nil, nil, errors.New("multiple top-level JSON elements found in strict mode")
+ } else {
+ jsonValue = values
+ }
+ }
+ return jsonValue, p.logger, nil
+}
+
+func (p *parser) parseJSON() (any, error) {
+ for {
+ char, ok := p.getCharAt(0)
+ if !ok {
+ return "", nil
+ }
+ if char == '{' {
+ p.index++
+ return p.parseObject()
+ }
+ if char == '[' {
+ p.index++
+ return p.parseArray()
+ }
+ if !p.context.empty && (isStringDelimiter(char) || unicode.IsLetter(char)) {
+ return p.parseString()
+ }
+ if !p.context.empty && (unicode.IsDigit(char) || char == '-' || char == '.') {
+ return p.parseNumber()
+ }
+ if p.context.empty && (unicode.IsDigit(char) || char == '-' || char == '.') {
+ if onlyWhitespaceBefore(p) {
+ return p.parseNumber()
+ }
+ }
+ if char == '#' || char == '/' {
+ return p.parseComment()
+ }
+ if !p.context.empty && (char == 't' || char == 'f' || char == 'n') {
+ value := p.parseBooleanOrNull()
+ if value != "" {
+ return value, nil
+ }
+ return p.parseString()
+ }
+ if p.context.empty && (char == 't' || char == 'f' || char == 'n') {
+ if onlyWhitespaceBefore(p) {
+ value := p.parseBooleanOrNull()
+ if value != "" {
+ return value, nil
+ }
+ }
+ }
+ if p.context.empty && char == ':' {
+ return "", nil
+ }
+ p.index++
+ }
+}
+
+func (p *parser) getCharAt(offset int) (rune, bool) {
+ idx := p.index + offset
+ if idx < 0 || idx >= len(p.jsonStr) {
+ return 0, false
+ }
+ return p.jsonStr[idx], true
+}
+
+func (p *parser) skipWhitespaces() {
+ for {
+ char, ok := p.getCharAt(0)
+ if !ok || !unicode.IsSpace(char) {
+ return
+ }
+ p.index++
+ }
+}
+
+func (p *parser) scrollWhitespaces(idx int) int {
+ for {
+ char, ok := p.getCharAt(idx)
+ if !ok || !unicode.IsSpace(char) {
+ return idx
+ }
+ idx++
+ }
+}
+
+func (p *parser) skipToCharacter(character rune, idx int) int {
+ targets := map[rune]struct{}{character: {}}
+ return p.skipToCharacters(targets, idx)
+}
+
+func (p *parser) skipToCharacters(targets map[rune]struct{}, idx int) int {
+ i := p.index + idx
+ backslashes := 0
+ for i < len(p.jsonStr) {
+ ch := p.jsonStr[i]
+ if ch == '\\' {
+ backslashes++
+ i++
+ continue
+ }
+ if _, ok := targets[ch]; ok && backslashes%2 == 0 {
+ return i - p.index
+ }
+ backslashes = 0
+ i++
+ }
+ return len(p.jsonStr) - p.index
+}
+
+func (p *parser) parseArray() (any, error) {
+ arr := []any{}
+ p.context.set(contextArray)
+ char, ok := p.getCharAt(0)
+ for ok && char != ']' && char != '}' {
+ p.skipWhitespaces()
+ var value any
+ if isStringDelimiter(char) {
+ i := 1
+ i = p.skipToCharacter(char, i)
+ i = p.scrollWhitespaces(i + 1)
+ if nextChar, ok := p.getCharAt(i); ok && nextChar == ':' {
+ value, _ = p.parseObject()
+ } else {
+ value, _ = p.parseString()
+ }
+ } else {
+ var err error
+ value, err = p.parseJSON()
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if isStrictlyEmpty(value) {
+ if nextChar, ok := p.getCharAt(0); !ok || (nextChar != ']' && nextChar != ',') {
+ p.index++
+ } else {
+ arr = append(arr, value)
+ }
+ } else if strVal, ok := value.(string); ok && strVal == "..." {
+ if prev, ok := p.getCharAt(-1); ok && prev == '.' {
+ p.log("While parsing an array, found a stray '...'; ignoring it")
+ } else {
+ arr = append(arr, value)
+ }
+ } else {
+ arr = append(arr, value)
+ }
+
+ char, ok = p.getCharAt(0)
+ for ok && char != ']' && (unicode.IsSpace(char) || char == ',') {
+ p.index++
+ char, ok = p.getCharAt(0)
+ }
+ }
+
+ if char != ']' {
+ p.log("While parsing an array we missed the closing ], ignoring it")
+ }
+
+ p.index++
+ p.context.reset()
+ return arr, nil
+}
+
+func (p *parser) parseComment() (any, error) {
+ char, ok := p.getCharAt(0)
+ if !ok {
+ return "", nil
+ }
+ termination := map[rune]struct{}{'\n': {}, '\r': {}}
+ if p.context.contains(contextArray) {
+ termination[']'] = struct{}{}
+ }
+ if p.context.contains(contextObjectValue) {
+ termination['}'] = struct{}{}
+ }
+ if p.context.contains(contextObjectKey) {
+ termination[':'] = struct{}{}
+ }
+ if char == '#' {
+ comment := []rune{}
+ for ok {
+ if _, hit := termination[char]; hit {
+ break
+ }
+ comment = append(comment, char)
+ p.index++
+ char, ok = p.getCharAt(0)
+ }
+ p.log("Found line comment: " + string(comment) + ", ignoring")
+ } else if char == '/' {
+ nextChar, ok := p.getCharAt(1)
+ if ok && nextChar == '/' {
+ comment := []rune{'/', '/'}
+ p.index += 2
+ char, ok = p.getCharAt(0)
+ for ok {
+ if _, hit := termination[char]; hit {
+ break
+ }
+ comment = append(comment, char)
+ p.index++
+ char, ok = p.getCharAt(0)
+ }
+ p.log("Found line comment: " + string(comment) + ", ignoring")
+ } else if ok && nextChar == '*' {
+ comment := []rune{'/', '*'}
+ p.index += 2
+ for {
+ char, ok = p.getCharAt(0)
+ if !ok {
+ p.log("Reached end-of-string while parsing block comment; unclosed block comment.")
+ break
+ }
+ comment = append(comment, char)
+ p.index++
+ if len(comment) >= 2 && comment[len(comment)-2] == '*' && comment[len(comment)-1] == '/' {
+ break
+ }
+ }
+ p.log("Found block comment: " + string(comment) + ", ignoring")
+ } else {
+ p.index++
+ }
+ }
+ if p.context.empty {
+ return p.parseJSON()
+ }
+ return "", nil
+}
+
+func (p *parser) parseNumber() (any, error) {
+ numberChars := "0123456789-.eE/,_"
+ numberStr := ""
+ char, ok := p.getCharAt(0)
+ isArray := p.context.current != nil && *p.context.current == contextArray
+ for ok && strings.ContainsRune(numberChars, char) && (!isArray || char != ',' || strings.Contains(numberStr, "/")) {
+ if char != '_' {
+ numberStr += string(char)
+ }
+ p.index++
+ char, ok = p.getCharAt(0)
+ }
+ if nextChar, ok := p.getCharAt(0); ok && unicode.IsLetter(nextChar) {
+ p.index -= len([]rune(numberStr))
+ return p.parseString()
+ }
+ if len(numberStr) > 0 {
+ last := numberStr[len(numberStr)-1]
+ if last == '-' || last == 'e' || last == 'E' || last == '/' || last == ',' {
+ numberStr = numberStr[:len(numberStr)-1]
+ p.index--
+ }
+ }
+ if strings.Contains(numberStr, "/") || strings.Contains(numberStr, "-") || strings.Contains(numberStr, ",") {
+ if numberStr == "-" {
+ return "", nil
+ }
+ if strings.ContainsAny(numberStr, "eE") {
+ floatVal, err := strconv.ParseFloat(numberStr, 64)
+ if err == nil {
+ formatted := formatFloat(floatVal)
+ return numberValue{raw: formatted}, nil
+ }
+ return numberStr, nil
+ }
+ return numberStr, nil
+ }
+ if strings.ContainsAny(numberStr, ".eE") {
+ floatVal, err := strconv.ParseFloat(numberStr, 64)
+ if err == nil {
+ formatted := formatFloat(floatVal)
+ return numberValue{raw: formatted}, nil
+ }
+ return numberStr, nil
+ }
+ if numberStr == "" {
+ return "", nil
+ }
+ return numberValue{raw: numberStr}, nil
+}
+
+func (p *parser) parseObject() (any, error) {
+ obj := newOrderedObject()
+ startIndex := p.index
+ for {
+ p.skipWhitespaces()
+ char, ok := p.getCharAt(0)
+ if !ok || char == '}' {
+ break
+ }
+ if current, ok := p.getCharAt(0); ok && current == ':' {
+ p.log("While parsing an object we found a : before a key, ignoring")
+ p.index++
+ }
+ p.context.set(contextObjectKey)
+ rollbackIndex := p.index
+ key := ""
+ for {
+ current, ok := p.getCharAt(0)
+ if !ok {
+ break
+ }
+ rollbackIndex = p.index
+ if current == '[' && key == "" {
+ prevKey, ok := obj.lastKey()
+ if ok {
+ prevValue, _ := obj.get(prevKey)
+ if prevArray, ok := prevValue.([]any); ok && !p.strict {
+ p.index++
+ newArrayValue, err := p.parseArray()
+ if err != nil {
+ return nil, err
+ }
+ if newArray, ok := newArrayValue.([]any); ok {
+ listLengths := []int{}
+ for _, item := range prevArray {
+ if nested, ok := item.([]any); ok {
+ listLengths = append(listLengths, len(nested))
+ }
+ }
+ expectedLen := 0
+ if len(listLengths) > 0 {
+ same := true
+ for _, length := range listLengths {
+ if length != listLengths[0] {
+ same = false
+ break
+ }
+ }
+ if same {
+ expectedLen = listLengths[0]
+ }
+ }
+ if expectedLen > 0 {
+ tail := []any{}
+ for len(prevArray) > 0 {
+ if _, ok := prevArray[len(prevArray)-1].([]any); ok {
+ break
+ }
+ tail = append(tail, prevArray[len(prevArray)-1])
+ prevArray = prevArray[:len(prevArray)-1]
+ }
+ if len(tail) > 0 {
+ reverseAny(tail)
+ if len(tail)%expectedLen == 0 {
+ p.log("While parsing an object we found row values without an inner array, grouping them into rows")
+ for i := 0; i < len(tail); i += expectedLen {
+ prevArray = append(prevArray, tail[i:i+expectedLen])
+ }
+ } else {
+ prevArray = append(prevArray, tail...)
+ }
+ }
+ if len(newArray) > 0 {
+ allLists := true
+ for _, item := range newArray {
+ if _, ok := item.([]any); !ok {
+ allLists = false
+ break
+ }
+ }
+ if allLists {
+ p.log("While parsing an object we found additional rows, appending them without flattening")
+ prevArray = append(prevArray, newArray...)
+ } else {
+ prevArray = append(prevArray, newArray)
+ }
+ }
+ } else {
+ if len(newArray) == 1 {
+ if nested, ok := newArray[0].([]any); ok {
+ prevArray = append(prevArray, nested...)
+ } else {
+ prevArray = append(prevArray, newArray...)
+ }
+ } else {
+ prevArray = append(prevArray, newArray...)
+ }
+ }
+ obj.set(prevKey, prevArray)
+ }
+ p.skipWhitespaces()
+ if nextChar, ok := p.getCharAt(0); ok && nextChar == ',' {
+ p.index++
+ }
+ p.skipWhitespaces()
+ continue
+ }
+ }
+ }
+ rawKeyValue, err := p.parseString()
+ if err != nil {
+ return nil, err
+ }
+ rawKey, _ := rawKeyValue.(string)
+ key = rawKey
+ if key == "" {
+ p.skipWhitespaces()
+ }
+ if key != "" || (key == "" && func() bool { ch, ok := p.getCharAt(0); return ok && (ch == ':' || ch == '}') }()) {
+ if key == "" && p.strict {
+ p.log("Empty key found in strict mode while parsing object, raising an error")
+ return nil, errors.New("empty key found in strict mode while parsing object")
+ }
+ break
+ }
+ }
+ if p.context.contains(contextArray) && obj.hasKey(key) {
+ if p.strict {
+ p.log("Duplicate key found in strict mode while parsing object, raising an error")
+ return nil, errors.New("duplicate key found in strict mode while parsing object")
+ }
+ p.log("While parsing an object we found a duplicate key, closing the object here and rolling back the index")
+ p.index = rollbackIndex - 1
+ p.insertRune(p.index+1, '{')
+ break
+ }
+ p.skipWhitespaces()
+ if current, ok := p.getCharAt(0); !ok || current == '}' {
+ continue
+ }
+ p.skipWhitespaces()
+ if current, ok := p.getCharAt(0); ok && current != ':' {
+ if p.strict {
+ p.log("Missing ':' after key in strict mode while parsing object, raising an error")
+ return nil, errors.New("missing ':' after key in strict mode while parsing object")
+ }
+ p.log("While parsing an object we missed a : after a key")
+ }
+ p.index++
+ p.context.reset()
+ p.context.set(contextObjectValue)
+ p.skipWhitespaces()
+ value := any("")
+ if current, ok := p.getCharAt(0); ok && (current == ',' || current == '}') {
+ p.log("While parsing an object value we found a stray " + string(current) + ", ignoring it")
+ } else {
+ var err error
+ value, err = p.parseJSON()
+ if err != nil {
+ return nil, err
+ }
+ }
+ if value == "" && p.strict {
+ if prev, ok := p.getCharAt(-1); !ok || !isStringDelimiter(prev) {
+ p.log("Parsed value is empty in strict mode while parsing object, raising an error")
+ return nil, errors.New("parsed value is empty in strict mode while parsing object")
+ }
+ }
+ p.context.reset()
+ obj.set(key, value)
+ if current, ok := p.getCharAt(0); ok && (current == ',' || current == '\'' || current == '"') {
+ p.index++
+ }
+ if current, ok := p.getCharAt(0); ok && current == ']' && p.context.contains(contextArray) {
+ p.log("While parsing an object we found a closing array bracket, closing the object here and rolling back the index")
+ p.index--
+ break
+ }
+ p.skipWhitespaces()
+ }
+ p.index++
+ if len(obj.entries) == 0 && p.index-startIndex > 2 {
+ if p.strict {
+ p.log("Parsed object is empty but contains extra characters in strict mode, raising an error")
+ return nil, errors.New("parsed object is empty but contains extra characters in strict mode")
+ }
+ if p.context.empty && p.index-startIndex <= 3 {
+ return obj, nil
+ }
+ if p.context.empty {
+ prefix := string(p.jsonStr[:startIndex-1])
+ if strings.TrimSpace(prefix) == "" {
+ return obj, nil
+ }
+ }
+ p.log("Parsed object is empty, we will try to parse this as an array instead")
+ p.index = startIndex
+ return p.parseArray()
+ }
+ if len(obj.entries) == 0 && p.index-startIndex <= 2 {
+ return obj, nil
+ }
+ if !p.context.empty {
+ if current, ok := p.getCharAt(0); ok && current == '}' {
+ if p.context.current == nil || (*p.context.current != contextObjectKey && *p.context.current != contextObjectValue) {
+ p.log("Found an extra closing brace that shouldn't be there, skipping it")
+ p.index++
+ }
+ }
+ return obj, nil
+ }
+ p.skipWhitespaces()
+ if current, ok := p.getCharAt(0); !ok || current != ',' {
+ return obj, nil
+ }
+ p.index++
+ p.skipWhitespaces()
+ if current, ok := p.getCharAt(0); !ok || !isStringDelimiter(current) {
+ return obj, nil
+ }
+ if !p.strict {
+ p.log("Found a comma and string delimiter after object closing brace, checking for additional key-value pairs")
+ additionalValue, err := p.parseObject()
+ if err != nil {
+ return nil, err
+ }
+ if additionalObj, ok := additionalValue.(*orderedObject); ok {
+ obj.merge(additionalObj)
+ }
+ }
+ return obj, nil
+}
+
+func (p *parser) parseString() (any, error) {
+ missingQuotes := false
+ doubledQuotes := false
+ ldelim := '"'
+ rdelim := '"'
+
+ char, ok := p.getCharAt(0)
+ if ok && (char == '#' || char == '/') {
+ return p.parseComment()
+ }
+ for ok && !isStringDelimiter(char) && !isAlphaNum(char) {
+ p.index++
+ char, ok = p.getCharAt(0)
+ }
+ if !ok {
+ return "", nil
+ }
+ if char == '\'' {
+ ldelim = '\''
+ rdelim = '\''
+ } else if char == 'ā' {
+ ldelim = 'ā'
+ rdelim = 'ā'
+ } else if isAlphaNum(char) {
+ if (char == 't' || char == 'f' || char == 'n') && (p.context.current == nil || *p.context.current != contextObjectKey) {
+ value := p.parseBooleanOrNull()
+ if value != "" {
+ return value, nil
+ }
+ }
+ if (char == 'T' || char == 'F' || char == 'N') && (p.context.current == nil || *p.context.current != contextObjectKey) {
+ value := p.parseBooleanOrNull()
+ if value != "" {
+ return value, nil
+ }
+ }
+ p.log("While parsing a string, we found a literal instead of a quote")
+ missingQuotes = true
+ }
+
+ if !missingQuotes {
+ p.index++
+ }
+ if next, ok := p.getCharAt(0); ok && next == '`' {
+ if value, ok := p.parseJSONLLMBlock(); ok {
+ return value, nil
+ }
+ if p.context.empty {
+ return "", nil
+ }
+ p.log("While parsing a string, we found code fences but they did not enclose valid JSON, continuing parsing the string")
+ }
+
+ if next, ok := p.getCharAt(0); ok && next == ldelim {
+ if (p.context.current != nil && *p.context.current == contextObjectKey && func() bool { ch, ok := p.getCharAt(1); return ok && ch == ':' }()) ||
+ (p.context.current != nil && *p.context.current == contextObjectValue && func() bool { ch, ok := p.getCharAt(1); return ok && (ch == ',' || ch == '}') }()) ||
+ (p.context.current != nil && *p.context.current == contextArray && func() bool { ch, ok := p.getCharAt(1); return ok && (ch == ',' || ch == ']') }()) {
+ p.index++
+ return "", nil
+ }
+ if p.context.current != nil && *p.context.current == contextObjectKey {
+ i := p.scrollWhitespaces(1)
+ if ch, ok := p.getCharAt(i); ok && ch == ':' {
+ p.index++
+ return "", nil
+ }
+ }
+ if next2, ok := p.getCharAt(1); ok && next2 == ldelim {
+ p.log("While parsing a string, we found a doubled quote and then a quote again, ignoring it")
+ if p.strict {
+ return nil, errors.New("found doubled quotes followed by another quote")
+ }
+ return "", nil
+ }
+ i := p.skipToCharacter(rdelim, 1)
+ if nextChar, ok := p.getCharAt(i + 1); ok && nextChar == rdelim {
+ p.log("While parsing a string, we found a valid starting doubled quote")
+ doubledQuotes = true
+ p.index++
+ } else {
+ i = p.scrollWhitespaces(1)
+ nextChar, ok := p.getCharAt(i)
+ if ok && (isStringDelimiter(nextChar) || nextChar == '{' || nextChar == '[') {
+ p.log("While parsing a string, we found a doubled quote but also another quote afterwards, ignoring it")
+ if p.strict {
+ return nil, errors.New("found doubled quotes followed by another quote while parsing a string")
+ }
+ p.index++
+ return "", nil
+ }
+ if !ok || (nextChar != ',' && nextChar != ']' && nextChar != '}') {
+ p.log("While parsing a string, we found a doubled quote but it was a mistake, removing one quote")
+ p.index++
+ }
+ }
+ }
+
+ stringAcc := []rune{}
+ char, ok = p.getCharAt(0)
+ unmatchedDelimiter := false
+ for ok && char != rdelim {
+ if missingQuotes {
+ if p.context.current != nil && *p.context.current == contextObjectKey {
+ if char == ':' || unicode.IsSpace(char) {
+ p.log("While parsing a string missing the left delimiter in object key context, we found a :, stopping here")
+ break
+ }
+ }
+ if p.context.current != nil && *p.context.current == contextArray {
+ if char == ']' || char == ',' {
+ p.log("While parsing a string missing the left delimiter in array context, we found a ] or ,, stopping here")
+ break
+ }
+ }
+ }
+ if !p.streamStable && p.context.current != nil && *p.context.current == contextObjectValue {
+ if (char == ',' || char == '}') && (len(stringAcc) == 0 || stringAcc[len(stringAcc)-1] != rdelim) {
+ rstringDelimiterMissing := true
+ next := rune(0)
+ p.skipWhitespaces()
+ if next, ok := p.getCharAt(1); ok && next == '\\' {
+ rstringDelimiterMissing = false
+ }
+ i := p.skipToCharacter(rdelim, 1)
+ if _, ok := p.getCharAt(i); ok {
+ i++
+ i = p.scrollWhitespaces(i)
+ next, _ = p.getCharAt(i)
+ if next == ',' || next == '}' {
+ rstringDelimiterMissing = false
+ } else {
+ i = p.skipToCharacter(ldelim, i)
+ if _, ok := p.getCharAt(i); !ok {
+ rstringDelimiterMissing = false
+ } else {
+ i = p.scrollWhitespaces(i + 1)
+ next, _ = p.getCharAt(i)
+ if next != ':' {
+ rstringDelimiterMissing = false
+ }
+ }
+ }
+ } else {
+ i = p.skipToCharacter(':', 1)
+ if _, ok := p.getCharAt(i); ok {
+ break
+ }
+ i = p.scrollWhitespaces(1)
+ j := p.skipToCharacter('}', i)
+ if j-i > 1 {
+ rstringDelimiterMissing = false
+ } else if _, ok := p.getCharAt(j); ok {
+ for k := len(stringAcc) - 1; k >= 0; k-- {
+ if stringAcc[k] == '{' {
+ rstringDelimiterMissing = false
+ break
+ }
+ }
+ }
+ }
+ if rstringDelimiterMissing {
+ p.log("While parsing a string missing the left delimiter in object value context, we found a , or } and we couldn't determine that a right delimiter was present. Stopping here")
+ break
+ }
+ }
+ }
+ if !p.streamStable && p.context.contains(contextArray) && char == ']' {
+ i := p.skipToCharacter(rdelim, 0)
+ if _, ok := p.getCharAt(i); !ok {
+ break
+ }
+ }
+ if p.context.current != nil && *p.context.current == contextObjectValue && char == '}' {
+ i := p.scrollWhitespaces(1)
+ nextChar, ok := p.getCharAt(i)
+ if ok && nextChar == '`' {
+ if c1, ok := p.getCharAt(i + 1); ok && c1 == '`' {
+ if c2, ok := p.getCharAt(i + 2); ok && c2 == '`' {
+ p.log("While parsing a string in object value context, we found a } that closes the object before code fences, stopping here")
+ break
+ }
+ }
+ }
+ if !ok {
+ p.log("While parsing a string in object value context, we found a } that closes the object, stopping here")
+ break
+ }
+ }
+ stringAcc = append(stringAcc, char)
+ p.index++
+ char, ok = p.getCharAt(0)
+ if !ok {
+ if p.streamStable && len(stringAcc) > 0 && stringAcc[len(stringAcc)-1] == '\\' {
+ stringAcc = stringAcc[:len(stringAcc)-1]
+ }
+ break
+ }
+ if len(stringAcc) > 0 && stringAcc[len(stringAcc)-1] == '\\' {
+ p.log("Found a stray escape sequence, normalizing it")
+ if char == rdelim || char == 't' || char == 'n' || char == 'r' || char == 'b' || char == '\\' {
+ stringAcc = stringAcc[:len(stringAcc)-1]
+ escapeSeqs := map[rune]rune{'t': '\t', 'n': '\n', 'r': '\r', 'b': '\b'}
+ if replacement, ok := escapeSeqs[char]; ok {
+ stringAcc = append(stringAcc, replacement)
+ } else {
+ stringAcc = append(stringAcc, char)
+ }
+ p.index++
+ char, ok = p.getCharAt(0)
+ for ok && len(stringAcc) > 0 && stringAcc[len(stringAcc)-1] == '\\' && (char == rdelim || char == '\\') {
+ stringAcc = append(stringAcc[:len(stringAcc)-1], char)
+ p.index++
+ char, ok = p.getCharAt(0)
+ }
+ continue
+ }
+ if char == 'u' || char == 'x' {
+ numChars := 4
+ if char == 'x' {
+ numChars = 2
+ }
+ nextChars := p.sliceRunes(p.index+1, p.index+1+numChars)
+ if len(nextChars) == numChars && isHexString(string(nextChars)) {
+ p.log("Found a unicode escape sequence, normalizing it")
+ parsed, _ := strconv.ParseInt(string(nextChars), 16, 32)
+ stringAcc = append(stringAcc[:len(stringAcc)-1], rune(parsed))
+ p.index += 1 + numChars
+ char, ok = p.getCharAt(0)
+ continue
+ }
+ } else if isStringDelimiter(char) && char != rdelim {
+ p.log("Found a delimiter that was escaped but shouldn't be escaped, removing the escape")
+ stringAcc = append(stringAcc[:len(stringAcc)-1], char)
+ p.index++
+ char, ok = p.getCharAt(0)
+ continue
+ }
+ }
+ if char == ':' && !missingQuotes && p.context.current != nil && *p.context.current == contextObjectKey {
+ i := p.skipToCharacter(ldelim, 1)
+ if _, ok := p.getCharAt(i); ok {
+ i++
+ i = p.skipToCharacter(rdelim, i)
+ if _, ok := p.getCharAt(i); ok {
+ i++
+ i = p.scrollWhitespaces(i)
+ ch, ok := p.getCharAt(i)
+ if ok && (ch == ',' || ch == '}') {
+ p.log("While parsing a string missing the right delimiter in object key context, we found a " + string(ch) + " stopping here")
+ break
+ }
+ }
+ } else {
+ p.log("While parsing a string missing the right delimiter in object key context, we found a :, stopping here")
+ break
+ }
+ }
+ if char == rdelim && (len(stringAcc) == 0 || stringAcc[len(stringAcc)-1] != '\\') {
+ if doubledQuotes {
+ if next, ok := p.getCharAt(1); ok && next == rdelim {
+ p.log("While parsing a string, we found a doubled quote, ignoring it")
+ p.index++
+ }
+ } else if missingQuotes && p.context.current != nil && *p.context.current == contextObjectValue {
+ i := 1
+ nextChar, ok := p.getCharAt(i)
+ for ok && nextChar != rdelim && nextChar != ldelim {
+ i++
+ nextChar, ok = p.getCharAt(i)
+ }
+ if ok {
+ i++
+ i = p.scrollWhitespaces(i)
+ if ch, ok := p.getCharAt(i); ok && ch == ':' {
+ p.index--
+ char, _ = p.getCharAt(0)
+ p.log("In a string with missing quotes and object value context, I found a delimeter but it turns out it was the beginning on the next key. Stopping here.")
+ break
+ }
+ }
+ } else if unmatchedDelimiter {
+ unmatchedDelimiter = false
+ stringAcc = append(stringAcc, char)
+ p.index++
+ char, ok = p.getCharAt(0)
+ } else {
+ i := 1
+ nextChar, ok := p.getCharAt(i)
+ checkCommaInObjectValue := true
+ for ok && nextChar != rdelim && nextChar != ldelim {
+ if checkCommaInObjectValue && unicode.IsLetter(nextChar) {
+ checkCommaInObjectValue = false
+ }
+ if (p.context.contains(contextObjectKey) && (nextChar == ':' || nextChar == '}')) ||
+ (p.context.contains(contextObjectValue) && nextChar == '}') ||
+ (p.context.contains(contextArray) && (nextChar == ']' || nextChar == ',')) ||
+ (checkCommaInObjectValue && p.context.current != nil && *p.context.current == contextObjectValue && nextChar == ',') {
+ break
+ }
+ i++
+ nextChar, ok = p.getCharAt(i)
+ }
+ if nextChar == ',' && p.context.current != nil && *p.context.current == contextObjectValue {
+ i++
+ i = p.skipToCharacter(rdelim, i)
+ i++
+ i = p.scrollWhitespaces(i)
+ nextChar, _ = p.getCharAt(i)
+ if nextChar == '}' || nextChar == ',' {
+ p.log("While parsing a string, we found a misplaced quote that would have closed the string but has a different meaning here, ignoring it")
+ stringAcc = append(stringAcc, char)
+ p.index++
+ char, ok = p.getCharAt(0)
+ if !ok {
+ break
+ }
+ continue
+ }
+ } else if nextChar == rdelim && func() bool { prev, ok := p.getCharAt(i - 1); return ok && prev != '\\' }() {
+ if onlyWhitespaceUntil(p, i) {
+ break
+ }
+ if p.context.current != nil && *p.context.current == contextObjectValue {
+ i = p.scrollWhitespaces(i + 1)
+ if ch, ok := p.getCharAt(i); ok && ch == ',' {
+ i = p.skipToCharacter(ldelim, i+1)
+ i++
+ i = p.skipToCharacter(rdelim, i+1)
+ i++
+ i = p.scrollWhitespaces(i)
+ if ch, ok := p.getCharAt(i); ok && ch == ':' {
+ p.log("While parsing a string, we found a misplaced quote that would have closed the string but has a different meaning here, ignoring it")
+ stringAcc = append(stringAcc, char)
+ p.index++
+ char, ok = p.getCharAt(0)
+ if !ok {
+ break
+ }
+ continue
+ }
+ }
+ i = p.skipToCharacter(rdelim, i+1)
+ i++
+ nextChar, ok = p.getCharAt(i)
+ for ok && nextChar != ':' {
+ if nextChar == ',' || nextChar == ']' || nextChar == '}' || (nextChar == rdelim && func() bool { prev, ok := p.getCharAt(i - 1); return ok && prev != '\\' }()) {
+ break
+ }
+ i++
+ nextChar, ok = p.getCharAt(i)
+ }
+ if nextChar != ':' {
+ p.log("While parsing a string, we found a misplaced quote that would have closed the string but has a different meaning here, ignoring it")
+ unmatchedDelimiter = !unmatchedDelimiter
+ stringAcc = append(stringAcc, char)
+ p.index++
+ char, ok = p.getCharAt(0)
+ if !ok {
+ break
+ }
+ }
+ } else if p.context.current != nil && *p.context.current == contextArray {
+ evenDelimiters := nextChar == rdelim
+ for nextChar == rdelim {
+ i = p.skipToCharacters(map[rune]struct{}{rdelim: {}, ']': {}}, i+1)
+ nextChar, ok = p.getCharAt(i)
+ if !ok || nextChar != rdelim {
+ evenDelimiters = false
+ break
+ }
+ i = p.skipToCharacters(map[rune]struct{}{rdelim: {}, ']': {}}, i+1)
+ nextChar, _ = p.getCharAt(i)
+ }
+ if evenDelimiters {
+ p.log("While parsing a string in Array context, we detected a quoted section that would have closed the string but has a different meaning here, ignoring it")
+ unmatchedDelimiter = !unmatchedDelimiter
+ stringAcc = append(stringAcc, char)
+ p.index++
+ char, ok = p.getCharAt(0)
+ if !ok {
+ break
+ }
+ } else {
+ break
+ }
+ } else if p.context.current != nil && *p.context.current == contextObjectKey {
+ p.log("While parsing a string in Object Key context, we detected a quoted section that would have closed the string but has a different meaning here, ignoring it")
+ stringAcc = append(stringAcc, char)
+ p.index++
+ char, ok = p.getCharAt(0)
+ if !ok {
+ break
+ }
+ }
+ }
+ }
+ }
+ }
+ if ok && missingQuotes && p.context.current != nil && *p.context.current == contextObjectKey && unicode.IsSpace(char) {
+ p.log("While parsing a string, handling an extreme corner case in which the LLM added a comment instead of valid string, invalidate the string and return an empty value")
+ p.skipWhitespaces()
+ if ch, ok := p.getCharAt(0); ok {
+ if ch != ':' && ch != ',' {
+ p.index--
+ return "", nil
+ }
+ if ch == ',' {
+ p.index--
+ return "", nil
+ }
+ }
+ }
+ if missingQuotes && p.context.current != nil && *p.context.current == contextObjectKey {
+ if !onlyWhitespaceUntil(p, p.scrollWhitespaces(0)) {
+ stringAcc = trimRightWhitespace(stringAcc)
+ if len(stringAcc) == 0 {
+ return "", nil
+ }
+ }
+ }
+ if !ok || char != rdelim {
+ if !p.streamStable {
+ p.log("While parsing a string, we missed the closing quote, ignoring")
+ stringAcc = trimRightWhitespace(stringAcc)
+ }
+ } else {
+ p.index++
+ }
+ if !p.streamStable && (missingQuotes || (len(stringAcc) > 0 && stringAcc[len(stringAcc)-1] == '\n')) {
+ stringAcc = trimRightWhitespace(stringAcc)
+ }
+ if missingQuotes && p.context.empty {
+ next := p.scrollWhitespaces(0)
+ if ch, ok := p.getCharAt(next); ok && (ch == '{' || ch == '[' || ch == '`') {
+ return "", nil
+ }
+ if !p.streamStable {
+ stringAcc = trimRightWhitespace(stringAcc)
+ }
+ if len(stringAcc) == 0 {
+ return "", nil
+ }
+ }
+ if p.context.empty {
+ next := p.scrollWhitespaces(0)
+ if ch, ok := p.getCharAt(next); ok && (ch == '{' || ch == '[' || ch == '`') {
+ return "", nil
+ }
+ }
+ if len(stringAcc) == 1 && stringAcc[0] == rdelim {
+ return "", nil
+ }
+ if p.context.empty && missingQuotes {
+ if len(stringAcc) == 1 && stringAcc[0] == '"' {
+ return "", nil
+ }
+ }
+ return string(stringAcc), nil
+}
+
+func (p *parser) parseBooleanOrNull() any {
+ char, ok := p.getCharAt(0)
+ if !ok {
+ return ""
+ }
+ valueMap := map[rune]struct {
+ token string
+ value any
+ }{
+ 't': {"true", true},
+ 'f': {"false", false},
+ 'n': {"null", nil},
+ }
+ lower := unicode.ToLower(char)
+ value, ok := valueMap[lower]
+ if !ok {
+ return ""
+ }
+ matchUpper := unicode.IsUpper(char)
+ i := 0
+ startingIndex := p.index
+ current := lower
+ for ok && i < len(value.token) && current == rune(value.token[i]) {
+ i++
+ p.index++
+ char, ok = p.getCharAt(0)
+ if ok {
+ if unicode.IsUpper(char) {
+ matchUpper = true
+ }
+ current = unicode.ToLower(char)
+ }
+ }
+ if i == len(value.token) {
+ if matchUpper && p.context.empty {
+ p.index = startingIndex
+ return ""
+ }
+ return value.value
+ }
+ p.index = startingIndex
+ return ""
+}
+
+func (p *parser) parseJSONLLMBlock() (any, bool) {
+ if p.sliceString(p.index, p.index+7) == "```json" {
+ i := p.skipToCharacter('`', 7)
+ if p.sliceString(p.index+i, p.index+i+3) == "```" {
+ p.index += 7
+ value, err := p.parseJSON()
+ if err != nil {
+ return nil, false
+ }
+ return value, true
+ }
+ }
+ return nil, false
+}
+
+func (p *parser) sliceRunes(start int, end int) []rune {
+ if start < 0 {
+ start = 0
+ }
+ if end > len(p.jsonStr) {
+ end = len(p.jsonStr)
+ }
+ if start > end {
+ return []rune{}
+ }
+ return p.jsonStr[start:end]
+}
+
+func (p *parser) sliceString(start int, end int) string {
+ return string(p.sliceRunes(start, end))
+}
+
+func (p *parser) insertRune(pos int, r rune) {
+ if pos < 0 {
+ pos = 0
+ }
+ if pos > len(p.jsonStr) {
+ pos = len(p.jsonStr)
+ }
+ p.jsonStr = append(p.jsonStr[:pos], append([]rune{r}, p.jsonStr[pos:]...)...)
+}
+
+func onlyWhitespaceUntil(p *parser, end int) bool {
+ for j := 1; j < end; j++ {
+ c, ok := p.getCharAt(j)
+ if ok && !unicode.IsSpace(c) {
+ return false
+ }
+ }
+ return true
+}
+
+func onlyWhitespaceBefore(p *parser) bool {
+ for i := p.index - 1; i >= 0; i-- {
+ c := p.jsonStr[i]
+ if !unicode.IsSpace(c) {
+ return false
+ }
+ }
+ return true
+}
+
+func reverseAny(values []any) {
+ for i, j := 0, len(values)-1; i < j; i, j = i+1, j-1 {
+ values[i], values[j] = values[j], values[i]
+ }
+}
+
+func isStrictlyEmpty(value any) bool {
+ switch v := value.(type) {
+ case string:
+ return len(v) == 0
+ case []any:
+ return len(v) == 0
+ case *orderedObject:
+ return len(v.entries) == 0
+ default:
+ return false
+ }
+}
+
+func isSameObject(obj1 any, obj2 any) bool {
+ switch v1 := obj1.(type) {
+ case *orderedObject:
+ v2, ok := obj2.(*orderedObject)
+ if !ok {
+ return false
+ }
+ if len(v1.entries) != len(v2.entries) {
+ return false
+ }
+ for _, entry := range v1.entries {
+ val2, ok := v2.get(entry.key)
+ if !ok {
+ return false
+ }
+ if !isSameObject(entry.value, val2) {
+ return false
+ }
+ }
+ return true
+ case []any:
+ v2, ok := obj2.([]any)
+ if !ok {
+ return false
+ }
+ if len(v1) != len(v2) {
+ return false
+ }
+ for i := range v1 {
+ if !isSameObject(v1[i], v2[i]) {
+ return false
+ }
+ }
+ return true
+ default:
+ if obj1 == nil || obj2 == nil {
+ return obj1 == obj2
+ }
+ return reflect.TypeOf(obj1) == reflect.TypeOf(obj2)
+ }
+}
+
+func isTruthy(value any) bool {
+ switch v := value.(type) {
+ case string:
+ return v != ""
+ case []any:
+ return len(v) > 0
+ case *orderedObject:
+ return len(v.entries) > 0
+ case bool:
+ return v
+ case numberValue:
+ return v.raw != ""
+ case nil:
+ return false
+ default:
+ return true
+ }
+}
+
+func isStringDelimiter(char rune) bool {
+ switch char {
+ case '"', '\'', 'ā', 'ā':
+ return true
+ default:
+ return false
+ }
+}
+
+func isAlphaNum(char rune) bool {
+ return unicode.IsLetter(char) || unicode.IsDigit(char)
+}
+
+func trimRightWhitespace(values []rune) []rune {
+ for len(values) > 0 {
+ if !unicode.IsSpace(values[len(values)-1]) {
+ break
+ }
+ values = values[:len(values)-1]
+ }
+ return values
+}
+
+func isHexString(value string) bool {
+ if value == "" {
+ return false
+ }
+ for _, c := range value {
+ if (c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F') {
+ return false
+ }
+ }
+ return true
+}
+
+func formatFloat(value float64) string {
+ formatted := strconv.FormatFloat(value, 'f', -1, 64)
+ if !strings.Contains(formatted, ".") {
+ formatted += ".0"
+ }
+ return formatted
+}
+
+func applyOptions(opts []Option) options {
+ cfg := options{}
+ for _, opt := range opts {
+ if opt != nil {
+ opt(&cfg)
+ }
+ }
+ return cfg
+}
+
+func ensureASCIIValue(cfg options) bool {
+ if cfg.ensureASCII == nil {
+ return true
+ }
+ return *cfg.ensureASCII
+}
+
+// WithEnsureASCII sets whether to escape non-ASCII characters.
+func WithEnsureASCII(value bool) Option {
+ return func(o *options) {
+ o.ensureASCII = &value
+ }
+}
+
+// WithSkipJSONLoads skips JSON parsing during load.
+func WithSkipJSONLoads() Option {
+ return func(o *options) {
+ o.skipJSONLoads = true
+ }
+}
+
+// WithStreamStable enables streaming-stable parsing.
+func WithStreamStable() Option {
+ return func(o *options) {
+ o.streamStable = true
+ }
+}
+
+// WithStrict enables strict parsing mode.
+func WithStrict() Option {
+ return func(o *options) {
+ o.strict = true
+ }
+}
+
+// RepairJSON takes a potentially malformed JSON string output from LLMs and
+// attempts to repair it into a valid JSON string. It returns the repaired JSON
+// string or an error if the input cannot be repaired.
+func RepairJSON(input string, opts ...Option) (string, error) {
+ cfg := applyOptions(opts)
+ p := newParser(input, false, cfg.streamStable, cfg.strict)
+ value, _, err := p.parse()
+ if err != nil {
+ return "", err
+ }
+ if str, ok := value.(string); ok {
+ trimmed := strings.TrimSpace(str)
+ if str == "" || trimmed == "" {
+ return "", nil
+ }
+ return "", nil
+ }
+ if value == "" {
+ return "", nil
+ }
+ return serialize(value, ensureASCIIValue(cfg)), nil
+}
+
+// Loads takes a potentially malformed JSON string output from LLMs and attempts
+// to repair it and parse it into a Go value.
+func Loads(input string, opts ...Option) (any, error) {
+ cfg := applyOptions(opts)
+ p := newParser(input, false, cfg.streamStable, cfg.strict)
+ value, _, err := p.parse()
+ if err != nil {
+ return nil, err
+ }
+ if value == "" {
+ return "", nil
+ }
+ return normalizeValue(value), nil
+}
+
+// RepairJSONWithLog takes a potentially malformed JSON string output from LLMs
+// and attempts to repair it into a valid JSON string, while also returning logs
+// of the repair process.
+func RepairJSONWithLog(input string, opts ...Option) (any, []LogEntry, error) {
+ cfg := applyOptions(opts)
+ p := newParser(input, true, cfg.streamStable, cfg.strict)
+ value, logs, err := p.parse()
+ if err != nil {
+ return nil, nil, err
+ }
+ if logs == nil {
+ logs = []LogEntry{}
+ }
+ if value == "" {
+ return "", logs, nil
+ }
+ return normalizeValue(value), logs, nil
+}
+
+func normalizeValue(value any) any {
+ switch v := value.(type) {
+ case *orderedObject:
+ result := map[string]any{}
+ for _, entry := range v.entries {
+ result[entry.key] = normalizeValue(entry.value)
+ }
+ return result
+ case []any:
+ items := make([]any, 0, len(v))
+ for _, item := range v {
+ items = append(items, normalizeValue(item))
+ }
+ return items
+ case numberValue:
+ return json.Number(v.raw)
+ default:
+ return v
+ }
+}
+
+func serialize(value any, ensureASCII bool) string {
+ var buf bytes.Buffer
+ writeValue(&buf, value, ensureASCII)
+ return buf.String()
+}
+
+func writeValue(buf *bytes.Buffer, value any, ensureASCII bool) {
+ switch v := value.(type) {
+ case string:
+ buf.WriteByte('"')
+ writeEscapedString(buf, v, ensureASCII)
+ buf.WriteByte('"')
+ case numberValue:
+ buf.WriteString(v.raw)
+ case json.Number:
+ buf.WriteString(v.String())
+ case bool:
+ if v {
+ buf.WriteString("true")
+ } else {
+ buf.WriteString("false")
+ }
+ case nil:
+ buf.WriteString("null")
+ case []any:
+ buf.WriteByte('[')
+ for i, item := range v {
+ if i > 0 {
+ buf.WriteString(", ")
+ }
+ writeValue(buf, item, ensureASCII)
+ }
+ buf.WriteByte(']')
+ case *orderedObject:
+ buf.WriteByte('{')
+ for i, entry := range v.entries {
+ if i > 0 {
+ buf.WriteString(", ")
+ }
+ buf.WriteByte('"')
+ writeEscapedString(buf, entry.key, ensureASCII)
+ buf.WriteByte('"')
+ buf.WriteString(": ")
+ writeValue(buf, entry.value, ensureASCII)
+ }
+ buf.WriteByte('}')
+ case float64:
+ buf.WriteString(formatFloat(v))
+ case int:
+ buf.WriteString(strconv.Itoa(v))
+ case int64:
+ buf.WriteString(strconv.FormatInt(v, 10))
+ case uint64:
+ buf.WriteString(strconv.FormatUint(v, 10))
+ case map[string]any:
+ buf.WriteByte('{')
+ idx := 0
+ for key, item := range v {
+ if idx > 0 {
+ buf.WriteString(", ")
+ }
+ buf.WriteByte('"')
+ writeEscapedString(buf, key, ensureASCII)
+ buf.WriteByte('"')
+ buf.WriteString(": ")
+ writeValue(buf, item, ensureASCII)
+ idx++
+ }
+ buf.WriteByte('}')
+ default:
+ buf.WriteString("null")
+ }
+}
+
+func writeEscapedString(buf *bytes.Buffer, value string, ensureASCII bool) {
+ for _, r := range value {
+ switch r {
+ case '\\':
+ buf.WriteString("\\\\")
+ case '"':
+ buf.WriteString("\\\"")
+ case '\b':
+ buf.WriteString("\\b")
+ case '\f':
+ buf.WriteString("\\f")
+ case '\n':
+ buf.WriteString("\\n")
+ case '\r':
+ buf.WriteString("\\r")
+ case '\t':
+ buf.WriteString("\\t")
+ default:
+ if r < 0x20 {
+ buf.WriteString("\\u")
+ buf.WriteString(hex4(r))
+ continue
+ }
+ if ensureASCII && r > 0x7f {
+ if r > 0xFFFF {
+ for _, rr := range utf16.Encode([]rune{r}) {
+ buf.WriteString("\\u")
+ buf.WriteString(hex4(rune(rr)))
+ }
+ continue
+ }
+ buf.WriteString("\\u")
+ buf.WriteString(hex4(r))
+ continue
+ }
+ buf.WriteRune(r)
+ }
+ }
+}
+
+func hex4(r rune) string {
+ value := int(r)
+ result := strconv.FormatInt(int64(value), 16)
+ return strings.Repeat("0", 4-len(result)) + strings.ToLower(result)
+}
diff --git a/internal/fantasy/jsonrepair/jsonrepair_test.go b/internal/fantasy/jsonrepair/jsonrepair_test.go
new file mode 100644
index 000000000..5340543ff
--- /dev/null
+++ b/internal/fantasy/jsonrepair/jsonrepair_test.go
@@ -0,0 +1,1615 @@
+package jsonrepair
+
+import (
+ "encoding/json"
+ "reflect"
+ "strings"
+ "testing"
+)
+
+func TestRepairJSON(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ opts []Option
+ want string
+ }{
+ {
+ name: "valid_object",
+ input: "{\"name\": \"John\", \"age\": 30, \"city\": \"New York\"}",
+ want: "{\"name\": \"John\", \"age\": 30, \"city\": \"New York\"}",
+ },
+ {
+ name: "array_spacing",
+ input: "{\"employees\":[\"John\", \"Anna\", \"Peter\"]} ",
+ want: "{\"employees\": [\"John\", \"Anna\", \"Peter\"]}",
+ },
+ {
+ name: "colon_in_string",
+ input: "{\"key\": \"value:value\"}",
+ want: "{\"key\": \"value:value\"}",
+ },
+ {
+ name: "trailing_comma_in_string",
+ input: "{\"text\": \"The quick brown fox,\"}",
+ want: "{\"text\": \"The quick brown fox,\"}",
+ },
+ {
+ name: "apostrophe_in_string",
+ input: "{\"text\": \"The quick brown fox won't jump\"}",
+ want: "{\"text\": \"The quick brown fox won't jump\"}",
+ },
+ {
+ name: "missing_brace",
+ input: "{\"key\": \"\"",
+ want: "{\"key\": \"\"}",
+ },
+ {
+ name: "nested_object",
+ input: "{\"key1\": {\"key2\": [1, 2, 3]}}",
+ want: "{\"key1\": {\"key2\": [1, 2, 3]}}",
+ },
+ {
+ name: "large_integer",
+ input: "{\"key\": 12345678901234567890}",
+ want: "{\"key\": 12345678901234567890}",
+ },
+ {
+ name: "unicode_escape",
+ input: "{\"key\": \"valueāŗ\"}",
+ want: "{\"key\": \"value\\u263a\"}",
+ },
+ {
+ name: "escaped_newline",
+ input: "{\"key\": \"value\\nvalue\"}",
+ want: "{\"key\": \"value\\nvalue\"}",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := RepairJSON(tc.input, tc.opts...)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestRepairJSONMultipleTopLevel(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want string
+ }{
+ {
+ name: "array_then_object",
+ input: "[]{}",
+ want: "[]",
+ },
+ {
+ name: "array_then_object_with_value",
+ input: "[]{\"key\":\"value\"}",
+ want: "{\"key\": \"value\"}",
+ },
+ {
+ name: "object_then_array",
+ input: "{\"key\":\"value\"}[1,2,3,True]",
+ want: "[{\"key\": \"value\"}, [1, 2, 3, true]]",
+ },
+ {
+ name: "embedded_code_blocks",
+ input: "lorem ```json {\"key\":\"value\"} ``` ipsum ```json [1,2,3,True] ``` 42",
+ want: "[{\"key\": \"value\"}, [1, 2, 3, true]]",
+ },
+ {
+ name: "array_followed_by_array",
+ input: "[{\"key\":\"value\"}][{\"key\":\"value_after\"}]",
+ want: "[{\"key\": \"value_after\"}]",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := RepairJSON(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestRepairJSONEnsureASCII(t *testing.T) {
+ got, err := RepairJSON("{'test_äøå½äŗŗ_ascii':'ē»äøē '}", WithEnsureASCII(false))
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ want := "{\"test_äøå½äŗŗ_ascii\": \"ē»äøē \"}"
+ if got != want {
+ t.Fatalf("got %q want %q", got, want)
+ }
+}
+
+func TestRepairJSONStreamStable(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ opts []Option
+ want string
+ }{
+ {
+ name: "default_trailing_backslash",
+ input: "{\"key\": \"val\\",
+ want: "{\"key\": \"val\\\\\"}",
+ },
+ {
+ name: "default_trailing_newline",
+ input: "{\"key\": \"val\\n",
+ want: "{\"key\": \"val\"}",
+ },
+ {
+ name: "default_split_object",
+ input: "{\"key\": \"val\\n123,`key2:value2",
+ want: "{\"key\": \"val\\n123\", \"key2\": \"value2\"}",
+ },
+ {
+ name: "stable_trailing_backslash",
+ input: "{\"key\": \"val\\",
+ opts: []Option{WithStreamStable()},
+ want: "{\"key\": \"val\"}",
+ },
+ {
+ name: "stable_trailing_newline",
+ input: "{\"key\": \"val\\n",
+ opts: []Option{WithStreamStable()},
+ want: "{\"key\": \"val\\n\"}",
+ },
+ {
+ name: "stable_split_object",
+ input: "{\"key\": \"val\\n123,`key2:value2",
+ opts: []Option{WithStreamStable()},
+ want: "{\"key\": \"val\\n123,`key2:value2\"}",
+ },
+ {
+ name: "stable_complete_stream",
+ input: "{\"key\": \"val\\n123,`key2:value2`\"}",
+ opts: []Option{WithStreamStable()},
+ want: "{\"key\": \"val\\n123,`key2:value2`\"}",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := RepairJSON(tc.input, tc.opts...)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestLoads(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want any
+ }{
+ {
+ name: "empty_array",
+ input: "[]",
+ want: []any{},
+ },
+ {
+ name: "empty_object",
+ input: "{}",
+ want: map[string]any{},
+ },
+ {
+ name: "bools_nulls",
+ input: "{\"key\": true, \"key2\": false, \"key3\": null}",
+ want: map[string]any{
+ "key": true,
+ "key2": false,
+ "key3": nil,
+ },
+ },
+ {
+ name: "simple_object",
+ input: "{\"name\": \"John\", \"age\": 30, \"city\": \"New York\"}",
+ want: map[string]any{
+ "name": "John",
+ "age": json.Number("30"),
+ "city": "New York",
+ },
+ },
+ {
+ name: "array_numbers",
+ input: "[1, 2, 3, 4]",
+ want: []any{
+ json.Number("1"),
+ json.Number("2"),
+ json.Number("3"),
+ json.Number("4"),
+ },
+ },
+ {
+ name: "string_array",
+ input: "{\"employees\":[\"John\", \"Anna\", \"Peter\"]} ",
+ want: map[string]any{
+ "employees": []any{"John", "Anna", "Peter"},
+ },
+ },
+ {
+ name: "string_quotes_repaired",
+ input: "[{\"foo\": \"foo bar \"foobar\" foo bar baz.\", \"tag\": \"#foo-bar-foobar\"}]",
+ want: []any{
+ map[string]any{
+ "foo": "foo bar \"foobar\" foo bar baz.",
+ "tag": "#foo-bar-foobar",
+ },
+ },
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := Loads(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if !reflect.DeepEqual(got, tc.want) {
+ t.Fatalf("got %#v want %#v", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestRepairJSONSkipJSONLoads(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ opts []Option
+ want string
+ }{
+ {
+ name: "valid_json",
+ input: "{\"key\": true, \"key2\": false, \"key3\": null}",
+ opts: []Option{WithSkipJSONLoads()},
+ want: "{\"key\": true, \"key2\": false, \"key3\": null}",
+ },
+ {
+ name: "missing_value",
+ input: "{\"key\": true, \"key2\": false, \"key3\": }",
+ opts: []Option{WithSkipJSONLoads()},
+ want: "{\"key\": true, \"key2\": false, \"key3\": \"\"}",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := RepairJSON(tc.input, tc.opts...)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+
+ got, err := Loads("{\"key\": true, \"key2\": false, \"key3\": }", WithSkipJSONLoads())
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ want := map[string]any{
+ "key": true,
+ "key2": false,
+ "key3": "",
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Fatalf("got %#v want %#v", got, want)
+ }
+}
+
+func TestRepairJSONWithLog(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ wantValue any
+ wantLog []LogEntry
+ }{
+ {
+ name: "valid_json",
+ input: "{}",
+ wantValue: map[string]any{},
+ wantLog: []LogEntry{},
+ },
+ {
+ name: "missing_quote",
+ input: "{\"key\": \"value}",
+ wantValue: map[string]any{
+ "key": "value",
+ },
+ wantLog: []LogEntry{
+ {
+ Context: "y\": \"value}",
+ Text: "While parsing a string missing the left delimiter in object value context, we found a , or } and we couldn't determine that a right delimiter was present. Stopping here",
+ },
+ {
+ Context: "y\": \"value}",
+ Text: "While parsing a string, we missed the closing quote, ignoring",
+ },
+ },
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ gotValue, gotLog, err := RepairJSONWithLog(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if !reflect.DeepEqual(gotValue, tc.wantValue) {
+ t.Fatalf("got %#v want %#v", gotValue, tc.wantValue)
+ }
+ if !reflect.DeepEqual(gotLog, tc.wantLog) {
+ t.Fatalf("got %#v want %#v", gotLog, tc.wantLog)
+ }
+ })
+ }
+}
+
+func TestRepairJSONStrict(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ opts []Option
+ wantErr string
+ }{
+ {
+ name: "multiple_top_level",
+ input: "{\"key\":\"value\"}[\"value\"]",
+ opts: []Option{WithStrict()},
+ wantErr: "multiple top-level JSON elements",
+ },
+ {
+ name: "duplicate_keys_in_array",
+ input: "[{\"key\": \"first\", \"key\": \"second\"}]",
+ opts: []Option{WithStrict(), WithSkipJSONLoads()},
+ wantErr: "duplicate key found",
+ },
+ {
+ name: "empty_key",
+ input: "{\"\" : \"value\"}",
+ opts: []Option{WithStrict(), WithSkipJSONLoads()},
+ wantErr: "empty key found",
+ },
+ {
+ name: "missing_colon",
+ input: "{\"missing\" \"colon\"}",
+ opts: []Option{WithStrict()},
+ wantErr: "missing ':' after key",
+ },
+ {
+ name: "empty_value",
+ input: "{\"key\": , \"key2\": \"value2\"}",
+ opts: []Option{WithStrict(), WithSkipJSONLoads()},
+ wantErr: "parsed value is empty",
+ },
+ {
+ name: "empty_object_with_extra",
+ input: "{\"dangling\"}",
+ opts: []Option{WithStrict()},
+ wantErr: "parsed object is empty",
+ },
+ {
+ name: "immediate_doubled_quotes",
+ input: "{\"key\": \"\"\"\"}",
+ opts: []Option{WithStrict()},
+ wantErr: "doubled quotes followed by another quote",
+ },
+ {
+ name: "doubled_quotes_followed_by_string",
+ input: "{\"key\": \"\" \"value\"}",
+ opts: []Option{WithStrict()},
+ wantErr: "doubled quotes followed by another quote while parsing a string",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ _, err := RepairJSON(tc.input, tc.opts...)
+ if err == nil {
+ t.Fatalf("expected error")
+ }
+ if !strings.Contains(err.Error(), tc.wantErr) {
+ t.Fatalf("got %q want %q", err.Error(), tc.wantErr)
+ }
+ })
+ }
+}
+
+func TestParseArrayObjects(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want any
+ }{
+ {
+ name: "empty_array",
+ input: "[]",
+ want: []any{},
+ },
+ {
+ name: "numbers_array",
+ input: "[1, 2, 3, 4]",
+ want: []any{
+ json.Number("1"),
+ json.Number("2"),
+ json.Number("3"),
+ json.Number("4"),
+ },
+ },
+ {
+ name: "unfinished_array",
+ input: "[",
+ want: []any{},
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := Loads(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if !reflect.DeepEqual(got, tc.want) {
+ t.Fatalf("got %#v want %#v", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestParseArrayEdgeCases(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want string
+ }{
+ {
+ name: "nested_newlines",
+ input: "[[1\n\n]",
+ want: "[[1]]",
+ },
+ {
+ name: "array_with_object_end",
+ input: "[{]",
+ want: "[]",
+ },
+ {
+ name: "just_open_bracket",
+ input: "[",
+ want: "[]",
+ },
+ {
+ name: "dangling_quote",
+ input: "[\"",
+ want: "[]",
+ },
+ {
+ name: "just_close_bracket",
+ input: "]",
+ want: "",
+ },
+ {
+ name: "trailing_comma",
+ input: "[1, 2, 3,",
+ want: "[1, 2, 3]",
+ },
+ {
+ name: "ellipsis_end",
+ input: "[1, 2, 3, ...]",
+ want: "[1, 2, 3]",
+ },
+ {
+ name: "ellipsis_middle",
+ input: "[1, 2, ... , 3]",
+ want: "[1, 2, 3]",
+ },
+ {
+ name: "ellipsis_string",
+ input: "[1, 2, '...', 3]",
+ want: "[1, 2, \"...\", 3]",
+ },
+ {
+ name: "ellipsis_bools",
+ input: "[true, false, null, ...]",
+ want: "[true, false, null]",
+ },
+ {
+ name: "missing_commas",
+ input: "[\"a\" \"b\" \"c\" 1",
+ want: "[\"a\", \"b\", \"c\", 1]",
+ },
+ {
+ name: "object_array_missing_end",
+ input: "{\"employees\":[\"John\", \"Anna\",",
+ want: "{\"employees\": [\"John\", \"Anna\"]}",
+ },
+ {
+ name: "object_array_missing_quote",
+ input: "{\"employees\":[\"John\", \"Anna\", \"Peter",
+ want: "{\"employees\": [\"John\", \"Anna\", \"Peter\"]}",
+ },
+ {
+ name: "nested_object_array",
+ input: "{\"key1\": {\"key2\": [1, 2, 3",
+ want: "{\"key1\": {\"key2\": [1, 2, 3]}}",
+ },
+ {
+ name: "missing_array_quote",
+ input: "{\"key\": [\"value]}",
+ want: "{\"key\": [\"value\"]}",
+ },
+ {
+ name: "embedded_quotes",
+ input: "[\"lorem \"ipsum\" sic\"]",
+ want: "[\"lorem \\\"ipsum\\\" sic\"]",
+ },
+ {
+ name: "array_closes_object",
+ input: "{\"key1\": [\"value1\", \"value2\"}, \"key2\": [\"value3\", \"value4\"]}",
+ want: "{\"key1\": [\"value1\", \"value2\"], \"key2\": [\"value3\", \"value4\"]}",
+ },
+ {
+ name: "rows_missing_bracket",
+ input: "{\"headers\": [\"A\", \"B\", \"C\"], \"rows\": [[\"r1a\", \"r1b\", \"r1c\"], [\"r2a\", \"r2b\", \"r2c\"], \"r3a\", \"r3b\", \"r3c\"], [\"r4a\", \"r4b\", \"r4c\"], [\"r5a\", \"r5b\", \"r5c\"]]}",
+ want: "{\"headers\": [\"A\", \"B\", \"C\"], \"rows\": [[\"r1a\", \"r1b\", \"r1c\"], [\"r2a\", \"r2b\", \"r2c\"], [\"r3a\", \"r3b\", \"r3c\"], [\"r4a\", \"r4b\", \"r4c\"], [\"r5a\", \"r5b\", \"r5c\"]]}",
+ },
+ {
+ name: "array_missing_commas",
+ input: "{\"key\": [\"value\" \"value1\" \"value2\"]}",
+ want: "{\"key\": [\"value\", \"value1\", \"value2\"]}",
+ },
+ {
+ name: "array_many_quotes",
+ input: "{\"key\": [\"lorem \"ipsum\" dolor \"sit\" amet, \"consectetur\" \", \"lorem \"ipsum\" dolor\", \"lorem\"]}",
+ want: "{\"key\": [\"lorem \\\"ipsum\\\" dolor \\\"sit\\\" amet, \\\"consectetur\\\" \", \"lorem \\\"ipsum\\\" dolor\", \"lorem\"]}",
+ },
+ {
+ name: "quoted_key_characters",
+ input: "{\"k\"e\"y\": \"value\"}",
+ want: "{\"k\\\"e\\\"y\": \"value\"}",
+ },
+ {
+ name: "array_object_mixed",
+ input: "[\"key\":\"value\"}]",
+ want: "[{\"key\": \"value\"}]",
+ },
+ {
+ name: "array_object_followed_by_literal",
+ input: "[{\"key\": \"value\", \"key",
+ want: "[{\"key\": \"value\"}, [\"key\"]]",
+ },
+ {
+ name: "set_like_array",
+ input: "{'key1', 'key2'}",
+ want: "[\"key1\", \"key2\"]",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := RepairJSON(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestParseArrayMissingQuotes(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want string
+ }{
+ {
+ name: "value_missing_quote",
+ input: "[\"value1\" value2\", \"value3\"]",
+ want: "[\"value1\", \"value2\", \"value3\"]",
+ },
+ {
+ name: "comment_token",
+ input: "{\"bad_one\":[\"Lorem Ipsum\", \"consectetur\" comment\" ], \"good_one\":[ \"elit\", \"sed\", \"tempor\"]}",
+ want: "{\"bad_one\": [\"Lorem Ipsum\", \"consectetur\", \"comment\"], \"good_one\": [\"elit\", \"sed\", \"tempor\"]}",
+ },
+ {
+ name: "comment_token_no_space",
+ input: "{\"bad_one\": [\"Lorem Ipsum\",\"consectetur\" comment],\"good_one\": [\"elit\",\"sed\",\"tempor\"]}",
+ want: "{\"bad_one\": [\"Lorem Ipsum\", \"consectetur\", \"comment\"], \"good_one\": [\"elit\", \"sed\", \"tempor\"]}",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := RepairJSON(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestParseComment(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want string
+ }{
+ {
+ name: "just_slash",
+ input: "/",
+ want: "",
+ },
+ {
+ name: "block_comment_prefix",
+ input: "/* comment */ {\"key\": \"value\"}",
+ want: "{\"key\": \"value\"}",
+ },
+ {
+ name: "line_comment",
+ input: "{ \"key\": { \"key2\": \"value2\" // comment }, \"key3\": \"value3\" }",
+ want: "{\"key\": {\"key2\": \"value2\"}, \"key3\": \"value3\"}",
+ },
+ {
+ name: "hash_comment",
+ input: "{ \"key\": { \"key2\": \"value2\" # comment }, \"key3\": \"value3\" }",
+ want: "{\"key\": {\"key2\": \"value2\"}, \"key3\": \"value3\"}",
+ },
+ {
+ name: "block_comment_inside",
+ input: "{ \"key\": { \"key2\": \"value2\" /* comment */ }, \"key3\": \"value3\" }",
+ want: "{\"key\": {\"key2\": \"value2\"}, \"key3\": \"value3\"}",
+ },
+ {
+ name: "array_block_comment",
+ input: "[ \"value\", /* comment */ \"value2\" ]",
+ want: "[\"value\", \"value2\"]",
+ },
+ {
+ name: "unterminated_comment",
+ input: "{ \"key\": \"value\" /* comment",
+ want: "{\"key\": \"value\"}",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := RepairJSON(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestParseNumber(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want any
+ }{
+ {
+ name: "integer",
+ input: "1",
+ want: json.Number("1"),
+ },
+ {
+ name: "float",
+ input: "1.2",
+ want: json.Number("1.2"),
+ },
+ {
+ name: "underscored_integer",
+ input: "{\"value\": 82_461_110}",
+ want: map[string]any{
+ "value": json.Number("82461110"),
+ },
+ },
+ {
+ name: "underscored_float",
+ input: "{\"value\": 1_234.5_6}",
+ want: map[string]any{
+ "value": json.Number("1234.56"),
+ },
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := Loads(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if !reflect.DeepEqual(got, tc.want) {
+ t.Fatalf("got %#v want %#v", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestParseNumberEdgeCases(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want string
+ }{
+ {
+ name: "leading_dash",
+ input: " - { \"test_key\": [\"test_value\", \"test_value2\"] }",
+ want: "{\"test_key\": [\"test_value\", \"test_value2\"]}",
+ },
+ {
+ name: "fraction",
+ input: "{\"key\": 1/3}",
+ want: "{\"key\": \"1/3\"}",
+ },
+ {
+ name: "leading_decimal",
+ input: "{\"key\": .25}",
+ want: "{\"key\": 0.25}",
+ },
+ {
+ name: "fraction_in_object",
+ input: "{\"here\": \"now\", \"key\": 1/3, \"foo\": \"bar\"}",
+ want: "{\"here\": \"now\", \"key\": \"1/3\", \"foo\": \"bar\"}",
+ },
+ {
+ name: "fraction_long",
+ input: "{\"key\": 12345/67890}",
+ want: "{\"key\": \"12345/67890\"}",
+ },
+ {
+ name: "array_incomplete",
+ input: "[105,12",
+ want: "[105, 12]",
+ },
+ {
+ name: "object_numbers",
+ input: "{\"key\", 105,12,",
+ want: "{\"key\": \"105,12\"}",
+ },
+ {
+ name: "fraction_trailing",
+ input: "{\"key\": 1/3, \"foo\": \"bar\"}",
+ want: "{\"key\": \"1/3\", \"foo\": \"bar\"}",
+ },
+ {
+ name: "dash_number",
+ input: "{\"key\": 10-20}",
+ want: "{\"key\": \"10-20\"}",
+ },
+ {
+ name: "double_dot",
+ input: "{\"key\": 1.1.1}",
+ want: "{\"key\": \"1.1.1\"}",
+ },
+ {
+ name: "dash_array",
+ input: "[- ",
+ want: "[]",
+ },
+ {
+ name: "trailing_decimal",
+ input: "{\"key\": 1. }",
+ want: "{\"key\": 1.0}",
+ },
+ {
+ name: "exponent",
+ input: "{\"key\": 1e10 }",
+ want: "{\"key\": 10000000000.0}",
+ },
+ {
+ name: "bad_exponent",
+ input: "{\"key\": 1e }",
+ want: "{\"key\": 1}",
+ },
+ {
+ name: "non_number_suffix",
+ input: "{\"key\": 1notanumber }",
+ want: "{\"key\": \"1notanumber\"}",
+ },
+ {
+ name: "uuid_literal",
+ input: "{\"rowId\": 57eeeeb1-450b-482c-81b9-4be77e95dee2}",
+ want: "{\"rowId\": \"57eeeeb1-450b-482c-81b9-4be77e95dee2\"}",
+ },
+ {
+ name: "array_non_number",
+ input: "[1, 2notanumber]",
+ want: "[1, \"2notanumber\"]",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := RepairJSON(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestParseObjectObjects(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want any
+ }{
+ {
+ name: "empty_object",
+ input: "{}",
+ want: map[string]any{},
+ },
+ {
+ name: "object_values",
+ input: "{ \"key\": \"value\", \"key2\": 1, \"key3\": True }",
+ want: map[string]any{
+ "key": "value",
+ "key2": json.Number("1"),
+ "key3": true,
+ },
+ },
+ {
+ name: "unfinished_object",
+ input: "{",
+ want: map[string]any{},
+ },
+ {
+ name: "object_with_literals",
+ input: "{ \"key\": value, \"key2\": 1 \"key3\": null }",
+ want: map[string]any{
+ "key": "value",
+ "key2": json.Number("1"),
+ "key3": nil,
+ },
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := Loads(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if !reflect.DeepEqual(got, tc.want) {
+ t.Fatalf("got %#v want %#v", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestParseObjectEdgeCases(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want string
+ }{
+ {
+ name: "empty_trim",
+ input: " { } ",
+ want: "{}",
+ },
+ {
+ name: "just_open",
+ input: "{",
+ want: "{}",
+ },
+ {
+ name: "just_close",
+ input: "}",
+ want: "",
+ },
+ {
+ name: "dangling_quote",
+ input: "{\"",
+ want: "{}",
+ },
+ {
+ name: "object_array_merge",
+ input: "{foo: [}",
+ want: "{\"foo\": []}",
+ },
+ {
+ name: "empty_key",
+ input: "{\"\": \"value\"",
+ want: "{\"\": \"value\"}",
+ },
+ {
+ name: "embedded_quotes",
+ input: "{\"key\": \"v\"alue\"}",
+ want: "{\"key\": \"v\\\"alue\\\"\"}",
+ },
+ {
+ name: "comment_literal",
+ input: "{\"value_1\": true, COMMENT \"value_2\": \"data\"}",
+ want: "{\"value_1\": true, \"value_2\": \"data\"}",
+ },
+ {
+ name: "comment_literal_trailing",
+ input: "{\"value_1\": true, SHOULD_NOT_EXIST \"value_2\": \"data\" AAAA }",
+ want: "{\"value_1\": true, \"value_2\": \"data\"}",
+ },
+ {
+ name: "empty_key_bool",
+ input: "{\"\" : true, \"key2\": \"value2\"}",
+ want: "{\"\": true, \"key2\": \"value2\"}",
+ },
+ {
+ name: "double_quotes",
+ input: "{\"\"answer\"\":[{\"\"traits\"\":''Female aged 60+'',\"\"answer1\"\":\"\"5\"\"}]}",
+ want: "{\"answer\": [{\"traits\": \"Female aged 60+\", \"answer1\": \"5\"}]}",
+ },
+ {
+ name: "missing_quotes",
+ input: "{ \"words\": abcdef\", \"numbers\": 12345\", \"words2\": ghijkl\" }",
+ want: "{\"words\": \"abcdef\", \"numbers\": 12345, \"words2\": \"ghijkl\"}",
+ },
+ {
+ name: "broken_split_key",
+ input: "{\"number\": 1,\"reason\": \"According...\"\"ans\": \"YES\"}",
+ want: "{\"number\": 1, \"reason\": \"According...\", \"ans\": \"YES\"}",
+ },
+ {
+ name: "nested_braces_in_string",
+ input: "{ \"a\" : \"{ b\": {} }\" }",
+ want: "{\"a\": \"{ b\"}",
+ },
+ {
+ name: "literal_after_string",
+ input: "{\"b\": \"xxxxx\" true}",
+ want: "{\"b\": \"xxxxx\"}",
+ },
+ {
+ name: "string_with_quotes",
+ input: "{\"key\": \"Lorem \"ipsum\" s,\"}",
+ want: "{\"key\": \"Lorem \\\"ipsum\\\" s,\"}",
+ },
+ {
+ name: "literal_list",
+ input: "{\"lorem\": ipsum, sic, datum.\",}",
+ want: "{\"lorem\": \"ipsum, sic, datum.\"}",
+ },
+ {
+ name: "multiple_keys",
+ input: "{\"lorem\": sic tamet. \"ipsum\": sic tamet, quick brown fox. \"sic\": ipsum}",
+ want: "{\"lorem\": \"sic tamet.\", \"ipsum\": \"sic tamet\", \"sic\": \"ipsum\"}",
+ },
+ {
+ name: "unfinished_string",
+ input: "{\"lorem_ipsum\": \"sic tamet, quick brown fox. }",
+ want: "{\"lorem_ipsum\": \"sic tamet, quick brown fox.\"}",
+ },
+ {
+ name: "missing_quotes_keys",
+ input: "{\"key\":value, \" key2\":\"value2\" }",
+ want: "{\"key\": \"value\", \" key2\": \"value2\"}",
+ },
+ {
+ name: "missing_quotes_key_separator",
+ input: "{\"key\":value \"key2\":\"value2\" }",
+ want: "{\"key\": \"value\", \"key2\": \"value2\"}",
+ },
+ {
+ name: "single_quotes_braces",
+ input: "{'text': 'words{words in brackets}more words'}",
+ want: "{\"text\": \"words{words in brackets}more words\"}",
+ },
+ {
+ name: "literal_with_braces",
+ input: "{text:words{words in brackets}}",
+ want: "{\"text\": \"words{words in brackets}\"}",
+ },
+ {
+ name: "literal_with_braces_suffix",
+ input: "{text:words{words in brackets}m}",
+ want: "{\"text\": \"words{words in brackets}m\"}",
+ },
+ {
+ name: "trailing_markdown",
+ input: "{\"key\": \"value, value2\"```",
+ want: "{\"key\": \"value, value2\"}",
+ },
+ {
+ name: "trailing_markdown_quote",
+ input: "{\"key\": \"value}```",
+ want: "{\"key\": \"value\"}",
+ },
+ {
+ name: "bare_keys",
+ input: "{key:value,key2:value2}",
+ want: "{\"key\": \"value\", \"key2\": \"value2\"}",
+ },
+ {
+ name: "missing_key_quote",
+ input: "{\"key:\"value\"}",
+ want: "{\"key\": \"value\"}",
+ },
+ {
+ name: "missing_value_quote",
+ input: "{\"key:value}",
+ want: "{\"key\": \"value\"}",
+ },
+ {
+ name: "array_double_quotes",
+ input: "[{\"lorem\": {\"ipsum\": \"sic\"}, \"\"\"\" \"lorem\": {\"ipsum\": \"sic\"}]",
+ want: "[{\"lorem\": {\"ipsum\": \"sic\"}}, {\"lorem\": {\"ipsum\": \"sic\"}}]",
+ },
+ {
+ name: "arrays_in_object",
+ input: "{ \"key\": [\"arrayvalue\"], [\"arrayvalue1\"], [\"arrayvalue2\"], \"key3\": \"value3\" }",
+ want: "{\"key\": [\"arrayvalue\", \"arrayvalue1\", \"arrayvalue2\"], \"key3\": \"value3\"}",
+ },
+ {
+ name: "nested_arrays_in_object",
+ input: "{ \"key\": [[1, 2, 3], \"a\", \"b\"], [[4, 5, 6], [7, 8, 9]] }",
+ want: "{\"key\": [[1, 2, 3], \"a\", \"b\", [4, 5, 6], [7, 8, 9]]}",
+ },
+ {
+ name: "array_key_missing_value",
+ input: "{ \"key\": [\"arrayvalue\"], \"key3\": \"value3\", [\"arrayvalue1\"] }",
+ want: "{\"key\": [\"arrayvalue\"], \"key3\": \"value3\", \"arrayvalue1\": \"\"}",
+ },
+ {
+ name: "json_string_literal",
+ input: "{\"key\": \"{\\\"key\\\":[\\\"value\\\"],\\\"key2\\\":\"value2\"}\"}",
+ want: "{\"key\": \"{\\\"key\\\":[\\\"value\\\"],\\\"key2\\\":\\\"value2\\\"}\"}",
+ },
+ {
+ name: "empty_value",
+ input: "{\"key\": , \"key2\": \"value2\"}",
+ want: "{\"key\": \"\", \"key2\": \"value2\"}",
+ },
+ {
+ name: "array_missing_object_end",
+ input: "{\"array\":[{\"key\": \"value\"], \"key2\": \"value2\"}",
+ want: "{\"array\": [{\"key\": \"value\"}], \"key2\": \"value2\"}",
+ },
+ {
+ name: "object_double_close",
+ input: "[{\"key\":\"value\"}},{\"key\":\"value\"}]",
+ want: "[{\"key\": \"value\"}, {\"key\": \"value\"}]",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := RepairJSON(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestParseObjectMergeAtEnd(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want string
+ }{
+ {
+ name: "merge_key",
+ input: "{\"key\": \"value\"}, \"key2\": \"value2\"}",
+ want: "{\"key\": \"value\", \"key2\": \"value2\"}",
+ },
+ {
+ name: "merge_empty_value",
+ input: "{\"key\": \"value\"}, \"key2\": }",
+ want: "{\"key\": \"value\", \"key2\": \"\"}",
+ },
+ {
+ name: "merge_array_discard",
+ input: "{\"key\": \"value\"}, []",
+ want: "{\"key\": \"value\"}",
+ },
+ {
+ name: "merge_array_keep",
+ input: "{\"key\": \"value\"}, [\"abc\"]",
+ want: "[{\"key\": \"value\"}, [\"abc\"]]",
+ },
+ {
+ name: "merge_object",
+ input: "{\"key\": \"value\"}, {}",
+ want: "{\"key\": \"value\"}",
+ },
+ {
+ name: "merge_empty_key",
+ input: "{\"key\": \"value\"}, \"\" : \"value2\"}",
+ want: "{\"key\": \"value\", \"\": \"value2\"}",
+ },
+ {
+ name: "merge_missing_colon",
+ input: "{\"key\": \"value\"}, \"key2\" \"value2\"}",
+ want: "{\"key\": \"value\", \"key2\": \"value2\"}",
+ },
+ {
+ name: "merge_multiple_keys",
+ input: "{\"key1\": \"value1\"}, \"key2\": \"value2\", \"key3\": \"value3\"}",
+ want: "{\"key1\": \"value1\", \"key2\": \"value2\", \"key3\": \"value3\"}",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := RepairJSON(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestParseStringBasics(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want string
+ }{
+ {
+ name: "just_quote",
+ input: "\"",
+ want: "",
+ },
+ {
+ name: "newline",
+ input: "\n",
+ want: "",
+ },
+ {
+ name: "space",
+ input: " ",
+ want: "",
+ },
+ {
+ name: "string_literal",
+ input: "string",
+ want: "",
+ },
+ {
+ name: "string_before_object",
+ input: "stringbeforeobject {}",
+ want: "{}",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := RepairJSON(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestMissingAndMixedQuotes(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want string
+ }{
+ {
+ name: "mixed_quotes",
+ input: "{'key': 'string', 'key2': false, \"key3\": null, \"key4\": unquoted}",
+ want: "{\"key\": \"string\", \"key2\": false, \"key3\": null, \"key4\": \"unquoted\"}",
+ },
+ {
+ name: "missing_last_quote",
+ input: "{\"name\": \"John\", \"age\": 30, \"city\": \"New York",
+ want: "{\"name\": \"John\", \"age\": 30, \"city\": \"New York\"}",
+ },
+ {
+ name: "missing_quotes_key",
+ input: "{\"name\": \"John\", \"age\": 30, city: \"New York\"}",
+ want: "{\"name\": \"John\", \"age\": 30, \"city\": \"New York\"}",
+ },
+ {
+ name: "missing_quotes_value",
+ input: "{\"name\": \"John\", \"age\": 30, \"city\": New York}",
+ want: "{\"name\": \"John\", \"age\": 30, \"city\": \"New York\"}",
+ },
+ {
+ name: "missing_quotes_value_with_name",
+ input: "{\"name\": John, \"age\": 30, \"city\": \"New York\"}",
+ want: "{\"name\": \"John\", \"age\": 30, \"city\": \"New York\"}",
+ },
+ {
+ name: "slanted_delimiter",
+ input: "{āslanted_delimiterā: \"value\"}",
+ want: "{\"slanted_delimiter\": \"value\"}",
+ },
+ {
+ name: "shortened_string",
+ input: "{\"name\": \"John\", \"age\": 30, \"city\": \"New",
+ want: "{\"name\": \"John\", \"age\": 30, \"city\": \"New\"}",
+ },
+ {
+ name: "missing_quote_in_middle",
+ input: "{\"name\": \"John\", \"age\": 30, \"city\": \"New York, \"gender\": \"male\"}",
+ want: "{\"name\": \"John\", \"age\": 30, \"city\": \"New York\", \"gender\": \"male\"}",
+ },
+ {
+ name: "comment_literal_in_array",
+ input: "[{\"key\": \"value\", COMMENT \"notes\": \"lorem \"ipsum\", sic.\" }]",
+ want: "[{\"key\": \"value\", \"notes\": \"lorem \\\"ipsum\\\", sic.\"}]",
+ },
+ {
+ name: "double_quote_prefix",
+ input: "{\"key\": \"\"value\"}",
+ want: "{\"key\": \"value\"}",
+ },
+ {
+ name: "numeric_key",
+ input: "{\"key\": \"value\", 5: \"value\"}",
+ want: "{\"key\": \"value\", \"5\": \"value\"}",
+ },
+ {
+ name: "escaped_quotes",
+ input: "{\"foo\": \"\\\\\"bar\\\\\"\"",
+ want: "{\"foo\": \"\\\"bar\\\"\"}",
+ },
+ {
+ name: "empty_key_prefix",
+ input: "{\"\" key\":\"val\"",
+ want: "{\" key\": \"val\"}",
+ },
+ {
+ name: "missing_comma",
+ input: "{\"key\": value \"key2\" : \"value2\" ",
+ want: "{\"key\": \"value\", \"key2\": \"value2\"}",
+ },
+ {
+ name: "ellipsis_quotes",
+ input: "{\"key\": \"lorem ipsum ... \"sic \" tamet. ...}",
+ want: "{\"key\": \"lorem ipsum ... \\\"sic \\\" tamet. ...\"}",
+ },
+ {
+ name: "trailing_comma",
+ input: "{\"key\": value , }",
+ want: "{\"key\": \"value\"}",
+ },
+ {
+ name: "comment_in_string",
+ input: "{\"comment\": \"lorem, \"ipsum\" sic \"tamet\". To improve\"}",
+ want: "{\"comment\": \"lorem, \\\"ipsum\\\" sic \\\"tamet\\\". To improve\"}",
+ },
+ {
+ name: "value_with_embedded_quotes",
+ input: "{\"key\": \"v\"alu\"e\"} key:",
+ want: "{\"key\": \"v\\\"alu\\\"e\"}",
+ },
+ {
+ name: "value_with_embedded_quote",
+ input: "{\"key\": \"v\"alue\", \"key2\": \"value2\"}",
+ want: "{\"key\": \"v\\\"alue\", \"key2\": \"value2\"}",
+ },
+ {
+ name: "array_value_with_quote",
+ input: "[{\"key\": \"v\"alu,e\", \"key2\": \"value2\"}]",
+ want: "[{\"key\": \"v\\\"alu,e\", \"key2\": \"value2\"}]",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := RepairJSON(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestEscaping(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want string
+ }{
+ {
+ name: "just_quotes",
+ input: "'\"'",
+ want: "",
+ },
+ {
+ name: "escaped_chars",
+ input: "{\"key\": 'string\"\n\t\\\\le'",
+ want: "{\"key\": \"string\\\"\\n\\t\\\\le\"}",
+ },
+ {
+ name: "html_escape",
+ input: "{\"real_content\": \"Some string: Some other string \\t Some string Some link\"",
+ want: "{\"real_content\": \"Some string: Some other string \\t Some string Some link\"}",
+ },
+ {
+ name: "newline_in_key",
+ input: "{\"key_1\n\": \"value\"}",
+ want: "{\"key_1\": \"value\"}",
+ },
+ {
+ name: "tab_in_key",
+ input: "{\"key\t_\": \"value\"}",
+ want: "{\"key\\t_\": \"value\"}",
+ },
+ {
+ name: "unicode_escape",
+ input: "{\"key\": '\u0076\u0061\u006c\u0075\u0065'}",
+ want: "{\"key\": \"value\"}",
+ },
+ {
+ name: "unicode_escape_skip_loads",
+ input: "{\"key\": \"\\u0076\\u0061\\u006C\\u0075\\u0065\"}",
+ want: "{\"key\": \"value\"}",
+ },
+ {
+ name: "escaped_single_quote",
+ input: "{\"key\": \"valu\\'e\"}",
+ want: "{\"key\": \"valu'e\"}",
+ },
+ {
+ name: "escaped_object",
+ input: "{'key': \"{\\\"key\\\": 1, \\\"key2\\\": 1}\"}",
+ want: "{\"key\": \"{\\\"key\\\": 1, \\\"key2\\\": 1}\"}",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ opts := []Option{}
+ if tc.name == "unicode_escape_skip_loads" {
+ opts = append(opts, WithSkipJSONLoads())
+ }
+ got, err := RepairJSON(tc.input, opts...)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestMarkdown(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want string
+ }{
+ {
+ name: "markdown_link",
+ input: "{ \"content\": \"[LINK](\"https://google.com\")\" }",
+ want: "{\"content\": \"[LINK](\\\"https://google.com\\\")\"}",
+ },
+ {
+ name: "markdown_incomplete",
+ input: "{ \"content\": \"[LINK](\" }",
+ want: "{\"content\": \"[LINK](\"}",
+ },
+ {
+ name: "markdown_in_object",
+ input: "{ \"content\": \"[LINK](\", \"key\": true }",
+ want: "{\"content\": \"[LINK](\", \"key\": true}",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := RepairJSON(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestLeadingTrailingCharacters(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want string
+ }{
+ {
+ name: "wrapped_markdown",
+ input: "````{ \"key\": \"value\" }```",
+ want: "{\"key\": \"value\"}",
+ },
+ {
+ name: "trailing_markdown_block",
+ input: "{ \"a\": \"\", \"b\": [ { \"c\": 1} ] \n}```",
+ want: "{\"a\": \"\", \"b\": [{\"c\": 1}]}",
+ },
+ {
+ name: "preface_text",
+ input: "Based on the information extracted, here is the filled JSON output: ```json { 'a': 'b' } ```",
+ want: "{\"a\": \"b\"}",
+ },
+ {
+ name: "multiline_markdown",
+ input: "\n The next 64 elements are:\n ```json\n { \"key\": \"value\" }\n ```",
+ want: "{\"key\": \"value\"}",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := RepairJSON(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestStringJSONLLMBlock(t *testing.T) {
+ cases := []struct {
+ name string
+ input string
+ want string
+ }{
+ {
+ name: "backticks",
+ input: "{\"key\": \"``\"",
+ want: "{\"key\": \"``\"}",
+ },
+ {
+ name: "backticks_json",
+ input: "{\"key\": \"```json\"",
+ want: "{\"key\": \"```json\"}",
+ },
+ {
+ name: "json_block_inside_string",
+ input: "{\"key\": \"```json {\"key\": [{\"key1\": 1},{\"key2\": 2}]}```\"}",
+ want: "{\"key\": {\"key\": [{\"key1\": 1}, {\"key2\": 2}]}}",
+ },
+ {
+ name: "response_prefix",
+ input: "{\"response\": \"```json{}\"",
+ want: "{\"response\": \"```json{}\"}",
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := RepairJSON(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestParseBooleanOrNull(t *testing.T) {
+ loadCases := []struct {
+ name string
+ input string
+ want any
+ }{
+ {
+ name: "upper_true",
+ input: "True",
+ want: "",
+ },
+ {
+ name: "upper_false",
+ input: "False",
+ want: "",
+ },
+ {
+ name: "upper_null",
+ input: "Null",
+ want: "",
+ },
+ {
+ name: "lower_true",
+ input: "true",
+ want: true,
+ },
+ {
+ name: "lower_false",
+ input: "false",
+ want: false,
+ },
+ {
+ name: "lower_null",
+ input: "null",
+ want: nil,
+ },
+ }
+
+ for _, tc := range loadCases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := Loads(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if !reflect.DeepEqual(got, tc.want) {
+ t.Fatalf("got %#v want %#v", got, tc.want)
+ }
+ })
+ }
+
+ stringCases := []struct {
+ name string
+ input string
+ want string
+ }{
+ {
+ name: "bools_in_object",
+ input: " {\"key\": true, \"key2\": false, \"key3\": null}",
+ want: "{\"key\": true, \"key2\": false, \"key3\": null}",
+ },
+ {
+ name: "uppercase_bools",
+ input: "{\"key\": TRUE, \"key2\": FALSE, \"key3\": Null} ",
+ want: "{\"key\": true, \"key2\": false, \"key3\": null}",
+ },
+ }
+
+ for _, tc := range stringCases {
+ t.Run(tc.name, func(t *testing.T) {
+ got, err := RepairJSON(tc.input)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if got != tc.want {
+ t.Fatalf("got %q want %q", got, tc.want)
+ }
+ })
+ }
+}
diff --git a/internal/fantasy/model.go b/internal/fantasy/model.go
new file mode 100644
index 000000000..4d1c3e31b
--- /dev/null
+++ b/internal/fantasy/model.go
@@ -0,0 +1,258 @@
+package fantasy
+
+import (
+ "context"
+ "fmt"
+ "iter"
+ "strings"
+)
+
+// Usage represents token usage statistics for a model call.
+type Usage struct {
+ InputTokens int64 `json:"input_tokens"`
+ OutputTokens int64 `json:"output_tokens"`
+ TotalTokens int64 `json:"total_tokens"`
+ ReasoningTokens int64 `json:"reasoning_tokens"`
+ CacheCreationTokens int64 `json:"cache_creation_tokens"`
+ CacheReadTokens int64 `json:"cache_read_tokens"`
+}
+
+func (u Usage) String() string {
+ return fmt.Sprintf("Usage{Input: %d, Output: %d, Total: %d, Reasoning: %d, CacheCreation: %d, CacheRead: %d}",
+ u.InputTokens,
+ u.OutputTokens,
+ u.TotalTokens,
+ u.ReasoningTokens,
+ u.CacheCreationTokens,
+ u.CacheReadTokens,
+ )
+}
+
+// ResponseContent represents the content of a model response.
+type ResponseContent []Content
+
+// Text returns the text content of the response.
+func (r ResponseContent) Text() string {
+ for _, c := range r {
+ if c.GetType() == ContentTypeText {
+ if textContent, ok := AsContentType[TextContent](c); ok {
+ return textContent.Text
+ }
+ }
+ }
+ return ""
+}
+
+// Reasoning returns all reasoning content parts.
+func (r ResponseContent) Reasoning() []ReasoningContent {
+ var reasoning []ReasoningContent
+ for _, c := range r {
+ if c.GetType() == ContentTypeReasoning {
+ if reasoningContent, ok := AsContentType[ReasoningContent](c); ok {
+ reasoning = append(reasoning, reasoningContent)
+ }
+ }
+ }
+ return reasoning
+}
+
+// ReasoningText returns all reasoning content as a concatenated string.
+func (r ResponseContent) ReasoningText() string {
+ var builder strings.Builder
+ for _, reasoning := range r.Reasoning() {
+ builder.WriteString(reasoning.Text)
+ }
+ return builder.String()
+}
+
+// Files returns all file content parts.
+func (r ResponseContent) Files() []FileContent {
+ var files []FileContent
+ for _, c := range r {
+ if c.GetType() == ContentTypeFile {
+ if fileContent, ok := AsContentType[FileContent](c); ok {
+ files = append(files, fileContent)
+ }
+ }
+ }
+ return files
+}
+
+// Sources returns all source content parts.
+func (r ResponseContent) Sources() []SourceContent {
+ var sources []SourceContent
+ for _, c := range r {
+ if c.GetType() == ContentTypeSource {
+ if sourceContent, ok := AsContentType[SourceContent](c); ok {
+ sources = append(sources, sourceContent)
+ }
+ }
+ }
+ return sources
+}
+
+// ToolCalls returns all tool call content parts.
+func (r ResponseContent) ToolCalls() []ToolCallContent {
+ var toolCalls []ToolCallContent
+ for _, c := range r {
+ if c.GetType() == ContentTypeToolCall {
+ if toolCallContent, ok := AsContentType[ToolCallContent](c); ok {
+ toolCalls = append(toolCalls, toolCallContent)
+ }
+ }
+ }
+ return toolCalls
+}
+
+// ToolResults returns all tool result content parts.
+func (r ResponseContent) ToolResults() []ToolResultContent {
+ var toolResults []ToolResultContent
+ for _, c := range r {
+ if c.GetType() == ContentTypeToolResult {
+ if toolResultContent, ok := AsContentType[ToolResultContent](c); ok {
+ toolResults = append(toolResults, toolResultContent)
+ }
+ }
+ }
+ return toolResults
+}
+
+// Response represents a response from a language model.
+type Response struct {
+ Content ResponseContent `json:"content"`
+ FinishReason FinishReason `json:"finish_reason"`
+ Usage Usage `json:"usage"`
+ Warnings []CallWarning `json:"warnings"`
+
+ // for provider specific response metadata, the key is the provider id
+ ProviderMetadata ProviderMetadata `json:"provider_metadata"`
+}
+
+// StreamPartType represents the type of a stream part.
+type StreamPartType string
+
+const (
+ // StreamPartTypeWarnings represents warnings stream part type.
+ StreamPartTypeWarnings StreamPartType = "warnings"
+ // StreamPartTypeTextStart represents text start stream part type.
+ StreamPartTypeTextStart StreamPartType = "text_start"
+ // StreamPartTypeTextDelta represents text delta stream part type.
+ StreamPartTypeTextDelta StreamPartType = "text_delta"
+ // StreamPartTypeTextEnd represents text end stream part type.
+ StreamPartTypeTextEnd StreamPartType = "text_end"
+
+ // StreamPartTypeReasoningStart represents reasoning start stream part type.
+ StreamPartTypeReasoningStart StreamPartType = "reasoning_start"
+ // StreamPartTypeReasoningDelta represents reasoning delta stream part type.
+ StreamPartTypeReasoningDelta StreamPartType = "reasoning_delta"
+ // StreamPartTypeReasoningEnd represents reasoning end stream part type.
+ StreamPartTypeReasoningEnd StreamPartType = "reasoning_end"
+ // StreamPartTypeToolInputStart represents tool input start stream part type.
+ StreamPartTypeToolInputStart StreamPartType = "tool_input_start"
+ // StreamPartTypeToolInputDelta represents tool input delta stream part type.
+ StreamPartTypeToolInputDelta StreamPartType = "tool_input_delta"
+ // StreamPartTypeToolInputEnd represents tool input end stream part type.
+ StreamPartTypeToolInputEnd StreamPartType = "tool_input_end"
+ // StreamPartTypeToolCall represents tool call stream part type.
+ StreamPartTypeToolCall StreamPartType = "tool_call"
+ // StreamPartTypeToolResult represents tool result stream part type.
+ StreamPartTypeToolResult StreamPartType = "tool_result"
+ // StreamPartTypeSource represents source stream part type.
+ StreamPartTypeSource StreamPartType = "source"
+ // StreamPartTypeFinish represents finish stream part type.
+ StreamPartTypeFinish StreamPartType = "finish"
+ // StreamPartTypeError represents error stream part type.
+ StreamPartTypeError StreamPartType = "error"
+)
+
+// StreamPart represents a part of a streaming response.
+type StreamPart struct {
+ Type StreamPartType `json:"type"`
+ ID string `json:"id"`
+ ToolCallName string `json:"tool_call_name"`
+ ToolCallInput string `json:"tool_call_input"`
+ Delta string `json:"delta"`
+ ProviderExecuted bool `json:"provider_executed"`
+ Usage Usage `json:"usage"`
+ FinishReason FinishReason `json:"finish_reason"`
+ Error error `json:"error"`
+ Warnings []CallWarning `json:"warnings"`
+
+ // Source-related fields
+ SourceType SourceType `json:"source_type"`
+ URL string `json:"url"`
+ Title string `json:"title"`
+
+ ProviderMetadata ProviderMetadata `json:"provider_metadata"`
+}
+
+// StreamResponse represents a streaming response sequence.
+type StreamResponse = iter.Seq[StreamPart]
+
+// ToolChoice represents the tool choice preference for a model call.
+type ToolChoice string
+
+const (
+ // ToolChoiceNone indicates no tools should be used.
+ ToolChoiceNone ToolChoice = "none"
+ // ToolChoiceAuto indicates tools should be used automatically.
+ ToolChoiceAuto ToolChoice = "auto"
+ // ToolChoiceRequired indicates tools are required.
+ ToolChoiceRequired ToolChoice = "required"
+)
+
+// SpecificToolChoice creates a tool choice for a specific tool name.
+func SpecificToolChoice(name string) ToolChoice {
+ return ToolChoice(name)
+}
+
+// Call represents a call to a language model.
+type Call struct {
+ Prompt Prompt `json:"prompt"`
+ MaxOutputTokens *int64 `json:"max_output_tokens"`
+ Temperature *float64 `json:"temperature"`
+ TopP *float64 `json:"top_p"`
+ TopK *int64 `json:"top_k"`
+ PresencePenalty *float64 `json:"presence_penalty"`
+ FrequencyPenalty *float64 `json:"frequency_penalty"`
+ Tools []Tool `json:"tools"`
+ ToolChoice *ToolChoice `json:"tool_choice"`
+
+ // for provider specific options, the key is the provider id
+ ProviderOptions ProviderOptions `json:"provider_options"`
+}
+
+// CallWarningType represents the type of call warning.
+type CallWarningType string
+
+const (
+ // CallWarningTypeUnsupportedSetting indicates an unsupported setting.
+ CallWarningTypeUnsupportedSetting CallWarningType = "unsupported-setting"
+ // CallWarningTypeUnsupportedTool indicates an unsupported tool.
+ CallWarningTypeUnsupportedTool CallWarningType = "unsupported-tool"
+ // CallWarningTypeOther indicates other warnings.
+ CallWarningTypeOther CallWarningType = "other"
+)
+
+// CallWarning represents a warning from the model provider for this call.
+// The call will proceed, but e.g. some settings might not be supported,
+// which can lead to suboptimal results.
+type CallWarning struct {
+ Type CallWarningType `json:"type"`
+ Setting string `json:"setting"`
+ Tool Tool `json:"tool"`
+ Details string `json:"details"`
+ Message string `json:"message"`
+}
+
+// LanguageModel represents a language model that can generate responses and stream responses.
+type LanguageModel interface {
+ Generate(context.Context, Call) (*Response, error)
+ Stream(context.Context, Call) (StreamResponse, error)
+
+ GenerateObject(context.Context, ObjectCall) (*ObjectResponse, error)
+ StreamObject(context.Context, ObjectCall) (ObjectStreamResponse, error)
+
+ Provider() string
+ Model() string
+}
diff --git a/internal/fantasy/model_json.go b/internal/fantasy/model_json.go
new file mode 100644
index 000000000..2fd883a2f
--- /dev/null
+++ b/internal/fantasy/model_json.go
@@ -0,0 +1,156 @@
+package fantasy
+
+import (
+ "encoding/json"
+ "fmt"
+)
+
+// UnmarshalJSON implements json.Unmarshaler for Call.
+func (c *Call) UnmarshalJSON(data []byte) error {
+ var aux struct {
+ Prompt Prompt `json:"prompt"`
+ MaxOutputTokens *int64 `json:"max_output_tokens"`
+ Temperature *float64 `json:"temperature"`
+ TopP *float64 `json:"top_p"`
+ TopK *int64 `json:"top_k"`
+ PresencePenalty *float64 `json:"presence_penalty"`
+ FrequencyPenalty *float64 `json:"frequency_penalty"`
+ Tools []json.RawMessage `json:"tools"`
+ ToolChoice *ToolChoice `json:"tool_choice"`
+ ProviderOptions map[string]json.RawMessage `json:"provider_options"`
+ }
+
+ if err := json.Unmarshal(data, &aux); err != nil {
+ return err
+ }
+
+ c.Prompt = aux.Prompt
+ c.MaxOutputTokens = aux.MaxOutputTokens
+ c.Temperature = aux.Temperature
+ c.TopP = aux.TopP
+ c.TopK = aux.TopK
+ c.PresencePenalty = aux.PresencePenalty
+ c.FrequencyPenalty = aux.FrequencyPenalty
+ c.ToolChoice = aux.ToolChoice
+
+ // Unmarshal Tools slice
+ c.Tools = make([]Tool, len(aux.Tools))
+ for i, rawTool := range aux.Tools {
+ tool, err := UnmarshalTool(rawTool)
+ if err != nil {
+ return fmt.Errorf("failed to unmarshal tool at index %d: %w", i, err)
+ }
+ c.Tools[i] = tool
+ }
+
+ // Unmarshal ProviderOptions
+ if len(aux.ProviderOptions) > 0 {
+ options, err := UnmarshalProviderOptions(aux.ProviderOptions)
+ if err != nil {
+ return err
+ }
+ c.ProviderOptions = options
+ }
+
+ return nil
+}
+
+// UnmarshalJSON implements json.Unmarshaler for Response.
+func (r *Response) UnmarshalJSON(data []byte) error {
+ var aux struct {
+ Content json.RawMessage `json:"content"`
+ FinishReason FinishReason `json:"finish_reason"`
+ Usage Usage `json:"usage"`
+ Warnings []CallWarning `json:"warnings"`
+ ProviderMetadata map[string]json.RawMessage `json:"provider_metadata"`
+ }
+
+ if err := json.Unmarshal(data, &aux); err != nil {
+ return err
+ }
+
+ r.FinishReason = aux.FinishReason
+ r.Usage = aux.Usage
+ r.Warnings = aux.Warnings
+
+ // Unmarshal ResponseContent (need to know the type definition)
+ // If ResponseContent is []Content:
+ var rawContent []json.RawMessage
+ if err := json.Unmarshal(aux.Content, &rawContent); err != nil {
+ return err
+ }
+
+ content := make([]Content, len(rawContent))
+ for i, rawItem := range rawContent {
+ item, err := UnmarshalContent(rawItem)
+ if err != nil {
+ return fmt.Errorf("failed to unmarshal content at index %d: %w", i, err)
+ }
+ content[i] = item
+ }
+ r.Content = content
+
+ // Unmarshal ProviderMetadata
+ if len(aux.ProviderMetadata) > 0 {
+ metadata, err := UnmarshalProviderMetadata(aux.ProviderMetadata)
+ if err != nil {
+ return err
+ }
+ r.ProviderMetadata = metadata
+ }
+
+ return nil
+}
+
+// MarshalJSON implements json.Marshaler for StreamPart.
+func (s StreamPart) MarshalJSON() ([]byte, error) {
+ type alias StreamPart
+ aux := struct {
+ alias
+ Error string `json:"error,omitempty"`
+ }{
+ alias: (alias)(s),
+ }
+
+ // Marshal error to string
+ if s.Error != nil {
+ aux.Error = s.Error.Error()
+ }
+
+ // Clear the original Error field to avoid duplicate marshaling
+ aux.alias.Error = nil
+
+ return json.Marshal(aux)
+}
+
+// UnmarshalJSON implements json.Unmarshaler for StreamPart.
+func (s *StreamPart) UnmarshalJSON(data []byte) error {
+ type alias StreamPart
+ aux := struct {
+ *alias
+ Error string `json:"error"`
+ ProviderMetadata map[string]json.RawMessage `json:"provider_metadata"`
+ }{
+ alias: (*alias)(s),
+ }
+
+ if err := json.Unmarshal(data, &aux); err != nil {
+ return err
+ }
+
+ // Unmarshal error string back to error type
+ if aux.Error != "" {
+ s.Error = fmt.Errorf("%s", aux.Error)
+ }
+
+ // Unmarshal ProviderMetadata
+ if len(aux.ProviderMetadata) > 0 {
+ metadata, err := UnmarshalProviderMetadata(aux.ProviderMetadata)
+ if err != nil {
+ return err
+ }
+ s.ProviderMetadata = metadata
+ }
+
+ return nil
+}
diff --git a/internal/fantasy/object.go b/internal/fantasy/object.go
new file mode 100644
index 000000000..4b8aed369
--- /dev/null
+++ b/internal/fantasy/object.go
@@ -0,0 +1,233 @@
+package fantasy
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "iter"
+ "reflect"
+
+ "charm.land/fantasy/schema"
+)
+
+// ObjectMode specifies how structured output should be generated.
+type ObjectMode string
+
+const (
+ // ObjectModeAuto lets the provider choose the best approach.
+ ObjectModeAuto ObjectMode = "auto"
+
+ // ObjectModeJSON forces the use of native JSON mode (if supported).
+ ObjectModeJSON ObjectMode = "json"
+
+ // ObjectModeTool forces the use of tool-based approach.
+ ObjectModeTool ObjectMode = "tool"
+
+ // ObjectModeText uses text generation with schema in prompt (fallback for models without tool/JSON support).
+ ObjectModeText ObjectMode = "text"
+)
+
+// ObjectCall represents a request to generate a structured object.
+type ObjectCall struct {
+ Prompt Prompt
+ Schema Schema
+ SchemaName string
+ SchemaDescription string
+
+ MaxOutputTokens *int64
+ Temperature *float64
+ TopP *float64
+ TopK *int64
+ PresencePenalty *float64
+ FrequencyPenalty *float64
+
+ ProviderOptions ProviderOptions
+
+ RepairText schema.ObjectRepairFunc
+}
+
+// ObjectResponse represents the response from a structured object generation.
+type ObjectResponse struct {
+ Object any
+ RawText string
+ Usage Usage
+ FinishReason FinishReason
+ Warnings []CallWarning
+ ProviderMetadata ProviderMetadata
+}
+
+// ObjectStreamPartType indicates the type of stream part.
+type ObjectStreamPartType string
+
+const (
+ // ObjectStreamPartTypeObject is emitted when a new partial object is available.
+ ObjectStreamPartTypeObject ObjectStreamPartType = "object"
+
+ // ObjectStreamPartTypeTextDelta is emitted for text deltas (if model generates text).
+ ObjectStreamPartTypeTextDelta ObjectStreamPartType = "text-delta"
+
+ // ObjectStreamPartTypeError is emitted when an error occurs.
+ ObjectStreamPartTypeError ObjectStreamPartType = "error"
+
+ // ObjectStreamPartTypeFinish is emitted when streaming completes.
+ ObjectStreamPartTypeFinish ObjectStreamPartType = "finish"
+)
+
+// ObjectStreamPart represents a single chunk in the object stream.
+type ObjectStreamPart struct {
+ Type ObjectStreamPartType
+ Object any
+ Delta string
+ Error error
+ Usage Usage
+ FinishReason FinishReason
+ Warnings []CallWarning
+ ProviderMetadata ProviderMetadata
+}
+
+// ObjectStreamResponse is an iterator over ObjectStreamPart.
+type ObjectStreamResponse = iter.Seq[ObjectStreamPart]
+
+// ObjectResult is a typed result wrapper returned by GenerateObject[T].
+type ObjectResult[T any] struct {
+ Object T
+ RawText string
+ Usage Usage
+ FinishReason FinishReason
+ Warnings []CallWarning
+ ProviderMetadata ProviderMetadata
+}
+
+// StreamObjectResult provides typed access to a streaming object generation result.
+type StreamObjectResult[T any] struct {
+ stream ObjectStreamResponse
+ ctx context.Context
+}
+
+// NewStreamObjectResult creates a typed stream result from an untyped stream.
+func NewStreamObjectResult[T any](ctx context.Context, stream ObjectStreamResponse) *StreamObjectResult[T] {
+ return &StreamObjectResult[T]{
+ stream: stream,
+ ctx: ctx,
+ }
+}
+
+// PartialObjectStream returns an iterator that yields progressively more complete objects.
+// Only emits when the object actually changes (deduplication).
+func (s *StreamObjectResult[T]) PartialObjectStream() iter.Seq[T] {
+ return func(yield func(T) bool) {
+ var lastObject T
+ var hasEmitted bool
+
+ for part := range s.stream {
+ if part.Type == ObjectStreamPartTypeObject && part.Object != nil {
+ var current T
+ if err := unmarshalObject(part.Object, ¤t); err != nil {
+ continue
+ }
+
+ if !hasEmitted || !reflect.DeepEqual(current, lastObject) {
+ if !yield(current) {
+ return
+ }
+ lastObject = current
+ hasEmitted = true
+ }
+ }
+ }
+ }
+}
+
+// TextStream returns an iterator that yields text deltas.
+// Useful if the model generates explanatory text alongside the object.
+func (s *StreamObjectResult[T]) TextStream() iter.Seq[string] {
+ return func(yield func(string) bool) {
+ for part := range s.stream {
+ if part.Type == ObjectStreamPartTypeTextDelta && part.Delta != "" {
+ if !yield(part.Delta) {
+ return
+ }
+ }
+ }
+ }
+}
+
+// FullStream returns an iterator that yields all stream parts including errors and metadata.
+func (s *StreamObjectResult[T]) FullStream() iter.Seq[ObjectStreamPart] {
+ return s.stream
+}
+
+// Object waits for the stream to complete and returns the final object.
+// Returns an error if streaming fails or no valid object was generated.
+func (s *StreamObjectResult[T]) Object() (*ObjectResult[T], error) {
+ var finalObject T
+ var usage Usage
+ var finishReason FinishReason
+ var warnings []CallWarning
+ var providerMetadata ProviderMetadata
+ var rawText string
+ var lastError error
+ hasObject := false
+
+ for part := range s.stream {
+ switch part.Type {
+ case ObjectStreamPartTypeObject:
+ if part.Object != nil {
+ if err := unmarshalObject(part.Object, &finalObject); err == nil {
+ hasObject = true
+ if jsonBytes, err := json.Marshal(part.Object); err == nil {
+ rawText = string(jsonBytes)
+ }
+ }
+ }
+
+ case ObjectStreamPartTypeError:
+ lastError = part.Error
+
+ case ObjectStreamPartTypeFinish:
+ usage = part.Usage
+ finishReason = part.FinishReason
+ if len(part.Warnings) > 0 {
+ warnings = part.Warnings
+ }
+ if len(part.ProviderMetadata) > 0 {
+ providerMetadata = part.ProviderMetadata
+ }
+ }
+ }
+
+ if lastError != nil {
+ return nil, lastError
+ }
+
+ if !hasObject {
+ return nil, &NoObjectGeneratedError{
+ RawText: rawText,
+ ParseError: fmt.Errorf("no valid object generated in stream"),
+ Usage: usage,
+ FinishReason: finishReason,
+ }
+ }
+
+ return &ObjectResult[T]{
+ Object: finalObject,
+ RawText: rawText,
+ Usage: usage,
+ FinishReason: finishReason,
+ Warnings: warnings,
+ ProviderMetadata: providerMetadata,
+ }, nil
+}
+
+func unmarshalObject(obj any, target any) error {
+ jsonBytes, err := json.Marshal(obj)
+ if err != nil {
+ return fmt.Errorf("failed to marshal object: %w", err)
+ }
+
+ if err := json.Unmarshal(jsonBytes, target); err != nil {
+ return fmt.Errorf("failed to unmarshal into target type: %w", err)
+ }
+
+ return nil
+}
diff --git a/internal/fantasy/object/object.go b/internal/fantasy/object/object.go
new file mode 100644
index 000000000..c62b1cbec
--- /dev/null
+++ b/internal/fantasy/object/object.go
@@ -0,0 +1,616 @@
+// Package object provides utilities for generating structured objects with automatic schema generation.
+// It simplifies working with typed structured outputs by handling schema reflection and unmarshaling.
+package object
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "reflect"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/schema"
+)
+
+// Generate generates a structured object that matches the given type T.
+// The schema is automatically generated from T using reflection.
+//
+// Example:
+//
+// type Recipe struct {
+// Name string `json:"name"`
+// Ingredients []string `json:"ingredients"`
+// }
+//
+// result, err := object.Generate[Recipe](ctx, model, fantasy.ObjectCall{
+// Prompt: fantasy.Prompt{fantasy.NewUserMessage("Generate a lasagna recipe")},
+// })
+func Generate[T any](
+ ctx context.Context,
+ model fantasy.LanguageModel,
+ opts fantasy.ObjectCall,
+) (*fantasy.ObjectResult[T], error) {
+ var zero T
+ s := schema.Generate(reflect.TypeOf(zero))
+ opts.Schema = s
+
+ resp, err := model.GenerateObject(ctx, opts)
+ if err != nil {
+ return nil, err
+ }
+
+ var result T
+ if err := unmarshal(resp.Object, &result); err != nil {
+ return nil, fmt.Errorf("failed to unmarshal to %T: %w", result, err)
+ }
+
+ return &fantasy.ObjectResult[T]{
+ Object: result,
+ RawText: resp.RawText,
+ Usage: resp.Usage,
+ FinishReason: resp.FinishReason,
+ Warnings: resp.Warnings,
+ ProviderMetadata: resp.ProviderMetadata,
+ }, nil
+}
+
+// Stream streams a structured object that matches the given type T.
+// Returns a StreamObjectResult[T] with progressive updates and deduplication.
+//
+// Example:
+//
+// stream, err := object.Stream[Recipe](ctx, model, fantasy.ObjectCall{
+// Prompt: fantasy.Prompt{fantasy.NewUserMessage("Generate a lasagna recipe")},
+// })
+//
+// for partial := range stream.PartialObjectStream() {
+// fmt.Printf("Progress: %s\n", partial.Name)
+// }
+//
+// result, err := stream.Object() // Wait for final result
+func Stream[T any](
+ ctx context.Context,
+ model fantasy.LanguageModel,
+ opts fantasy.ObjectCall,
+) (*fantasy.StreamObjectResult[T], error) {
+ var zero T
+ s := schema.Generate(reflect.TypeOf(zero))
+ opts.Schema = s
+
+ stream, err := model.StreamObject(ctx, opts)
+ if err != nil {
+ return nil, err
+ }
+
+ return fantasy.NewStreamObjectResult[T](ctx, stream), nil
+}
+
+// GenerateWithTool is a helper for providers without native JSON mode.
+// It converts the schema to a tool definition, forces the model to call it,
+// and extracts the tool's input as the structured output.
+func GenerateWithTool(
+ ctx context.Context,
+ model fantasy.LanguageModel,
+ call fantasy.ObjectCall,
+) (*fantasy.ObjectResponse, error) {
+ toolName := call.SchemaName
+ if toolName == "" {
+ toolName = "generate_object"
+ }
+
+ toolDescription := call.SchemaDescription
+ if toolDescription == "" {
+ toolDescription = "Generate a structured object matching the schema"
+ }
+
+ tool := fantasy.FunctionTool{
+ Name: toolName,
+ Description: toolDescription,
+ InputSchema: schema.ToMap(call.Schema),
+ }
+
+ toolChoice := fantasy.SpecificToolChoice(tool.Name)
+ resp, err := model.Generate(ctx, fantasy.Call{
+ Prompt: call.Prompt,
+ Tools: []fantasy.Tool{tool},
+ ToolChoice: &toolChoice,
+ MaxOutputTokens: call.MaxOutputTokens,
+ Temperature: call.Temperature,
+ TopP: call.TopP,
+ TopK: call.TopK,
+ PresencePenalty: call.PresencePenalty,
+ FrequencyPenalty: call.FrequencyPenalty,
+ ProviderOptions: call.ProviderOptions,
+ })
+ if err != nil {
+ return nil, fmt.Errorf("tool-based generation failed: %w", err)
+ }
+
+ toolCalls := resp.Content.ToolCalls()
+ if len(toolCalls) == 0 {
+ return nil, &fantasy.NoObjectGeneratedError{
+ RawText: resp.Content.Text(),
+ ParseError: fmt.Errorf("no tool call generated"),
+ Usage: resp.Usage,
+ FinishReason: resp.FinishReason,
+ }
+ }
+
+ toolCall := toolCalls[0]
+
+ var obj any
+ if call.RepairText != nil {
+ obj, err = schema.ParseAndValidateWithRepair(ctx, toolCall.Input, call.Schema, call.RepairText)
+ } else {
+ obj, err = schema.ParseAndValidate(toolCall.Input, call.Schema)
+ }
+
+ if err != nil {
+ if nogErr, ok := err.(*fantasy.NoObjectGeneratedError); ok {
+ nogErr.Usage = resp.Usage
+ nogErr.FinishReason = resp.FinishReason
+ }
+ return nil, err
+ }
+
+ return &fantasy.ObjectResponse{
+ Object: obj,
+ RawText: toolCall.Input,
+ Usage: resp.Usage,
+ FinishReason: resp.FinishReason,
+ Warnings: resp.Warnings,
+ ProviderMetadata: resp.ProviderMetadata,
+ }, nil
+}
+
+// GenerateWithText is a helper for providers without tool or JSON mode support.
+// It adds the schema to the system prompt and parses the text response as JSON.
+// This is a fallback for older models or simple providers.
+func GenerateWithText(
+ ctx context.Context,
+ model fantasy.LanguageModel,
+ call fantasy.ObjectCall,
+) (*fantasy.ObjectResponse, error) {
+ jsonSchemaBytes, err := json.Marshal(call.Schema)
+ if err != nil {
+ return nil, fmt.Errorf("failed to marshal schema: %w", err)
+ }
+
+ schemaInstruction := fmt.Sprintf(
+ "You must respond with valid JSON that matches this schema: %s\n"+
+ "Respond ONLY with the JSON object, no additional text or explanation.",
+ string(jsonSchemaBytes),
+ )
+
+ enhancedPrompt := make(fantasy.Prompt, 0, len(call.Prompt)+1)
+
+ hasSystem := false
+ for _, msg := range call.Prompt {
+ if msg.Role == fantasy.MessageRoleSystem {
+ hasSystem = true
+ existingText := ""
+ if len(msg.Content) > 0 {
+ if textPart, ok := msg.Content[0].(fantasy.TextPart); ok {
+ existingText = textPart.Text
+ }
+ }
+ enhancedPrompt = append(enhancedPrompt, fantasy.NewSystemMessage(existingText+"\n\n"+schemaInstruction))
+ } else {
+ enhancedPrompt = append(enhancedPrompt, msg)
+ }
+ }
+
+ if !hasSystem {
+ enhancedPrompt = append(fantasy.Prompt{fantasy.NewSystemMessage(schemaInstruction)}, call.Prompt...)
+ }
+
+ resp, err := model.Generate(ctx, fantasy.Call{
+ Prompt: enhancedPrompt,
+ MaxOutputTokens: call.MaxOutputTokens,
+ Temperature: call.Temperature,
+ TopP: call.TopP,
+ TopK: call.TopK,
+ PresencePenalty: call.PresencePenalty,
+ FrequencyPenalty: call.FrequencyPenalty,
+ ProviderOptions: call.ProviderOptions,
+ })
+ if err != nil {
+ return nil, fmt.Errorf("text-based generation failed: %w", err)
+ }
+
+ textContent := resp.Content.Text()
+ if textContent == "" {
+ return nil, &fantasy.NoObjectGeneratedError{
+ RawText: "",
+ ParseError: fmt.Errorf("no text content in response"),
+ Usage: resp.Usage,
+ FinishReason: resp.FinishReason,
+ }
+ }
+
+ var obj any
+ if call.RepairText != nil {
+ obj, err = schema.ParseAndValidateWithRepair(ctx, textContent, call.Schema, call.RepairText)
+ } else {
+ obj, err = schema.ParseAndValidate(textContent, call.Schema)
+ }
+
+ if err != nil {
+ if nogErr, ok := err.(*schema.ParseError); ok {
+ return nil, &fantasy.NoObjectGeneratedError{
+ RawText: nogErr.RawText,
+ ParseError: nogErr.ParseError,
+ ValidationError: nogErr.ValidationError,
+ Usage: resp.Usage,
+ FinishReason: resp.FinishReason,
+ }
+ }
+ return nil, err
+ }
+
+ return &fantasy.ObjectResponse{
+ Object: obj,
+ RawText: textContent,
+ Usage: resp.Usage,
+ FinishReason: resp.FinishReason,
+ Warnings: resp.Warnings,
+ ProviderMetadata: resp.ProviderMetadata,
+ }, nil
+}
+
+// StreamWithTool is a helper for providers without native JSON streaming.
+// It uses streaming tool calls to extract and parse the structured output progressively.
+func StreamWithTool(
+ ctx context.Context,
+ model fantasy.LanguageModel,
+ call fantasy.ObjectCall,
+) (fantasy.ObjectStreamResponse, error) {
+ // Create a tool from the schema
+ toolName := call.SchemaName
+ if toolName == "" {
+ toolName = "generate_object"
+ }
+
+ toolDescription := call.SchemaDescription
+ if toolDescription == "" {
+ toolDescription = "Generate a structured object matching the schema"
+ }
+
+ tool := fantasy.FunctionTool{
+ Name: toolName,
+ Description: toolDescription,
+ InputSchema: schema.ToMap(call.Schema),
+ }
+
+ // Make a streaming Generate call with forced tool choice
+ toolChoice := fantasy.SpecificToolChoice(tool.Name)
+ stream, err := model.Stream(ctx, fantasy.Call{
+ Prompt: call.Prompt,
+ Tools: []fantasy.Tool{tool},
+ ToolChoice: &toolChoice,
+ MaxOutputTokens: call.MaxOutputTokens,
+ Temperature: call.Temperature,
+ TopP: call.TopP,
+ TopK: call.TopK,
+ PresencePenalty: call.PresencePenalty,
+ FrequencyPenalty: call.FrequencyPenalty,
+ ProviderOptions: call.ProviderOptions,
+ })
+ if err != nil {
+ return nil, fmt.Errorf("tool-based streaming failed: %w", err)
+ }
+
+ // Convert the text stream to object stream parts
+ return func(yield func(fantasy.ObjectStreamPart) bool) {
+ var accumulated string
+ var lastParsedObject any
+ var usage fantasy.Usage
+ var finishReason fantasy.FinishReason
+ var warnings []fantasy.CallWarning
+ var providerMetadata fantasy.ProviderMetadata
+ var streamErr error
+
+ for part := range stream {
+ switch part.Type {
+ case fantasy.StreamPartTypeTextDelta:
+ accumulated += part.Delta
+
+ obj, state, parseErr := schema.ParsePartialJSON(accumulated)
+
+ if state == schema.ParseStateSuccessful || state == schema.ParseStateRepaired {
+ if err := schema.ValidateAgainstSchema(obj, call.Schema); err == nil {
+ if !reflect.DeepEqual(obj, lastParsedObject) {
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeObject,
+ Object: obj,
+ }) {
+ return
+ }
+ lastParsedObject = obj
+ }
+ }
+ }
+
+ if state == schema.ParseStateFailed && call.RepairText != nil {
+ repairedText, repairErr := call.RepairText(ctx, accumulated, parseErr)
+ if repairErr == nil {
+ obj2, state2, _ := schema.ParsePartialJSON(repairedText)
+ if (state2 == schema.ParseStateSuccessful || state2 == schema.ParseStateRepaired) &&
+ schema.ValidateAgainstSchema(obj2, call.Schema) == nil {
+ if !reflect.DeepEqual(obj2, lastParsedObject) {
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeObject,
+ Object: obj2,
+ }) {
+ return
+ }
+ lastParsedObject = obj2
+ }
+ }
+ }
+ }
+
+ case fantasy.StreamPartTypeToolInputDelta:
+ accumulated += part.Delta
+
+ obj, state, parseErr := schema.ParsePartialJSON(accumulated)
+ if state == schema.ParseStateSuccessful || state == schema.ParseStateRepaired {
+ if err := schema.ValidateAgainstSchema(obj, call.Schema); err == nil {
+ if !reflect.DeepEqual(obj, lastParsedObject) {
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeObject,
+ Object: obj,
+ }) {
+ return
+ }
+ lastParsedObject = obj
+ }
+ }
+ }
+
+ if state == schema.ParseStateFailed && call.RepairText != nil {
+ repairedText, repairErr := call.RepairText(ctx, accumulated, parseErr)
+ if repairErr == nil {
+ obj2, state2, _ := schema.ParsePartialJSON(repairedText)
+ if (state2 == schema.ParseStateSuccessful || state2 == schema.ParseStateRepaired) &&
+ schema.ValidateAgainstSchema(obj2, call.Schema) == nil {
+ if !reflect.DeepEqual(obj2, lastParsedObject) {
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeObject,
+ Object: obj2,
+ }) {
+ return
+ }
+ lastParsedObject = obj2
+ }
+ }
+ }
+ }
+
+ case fantasy.StreamPartTypeToolCall:
+ toolInput := part.ToolCallInput
+
+ var obj any
+ var err error
+ if call.RepairText != nil {
+ obj, err = schema.ParseAndValidateWithRepair(ctx, toolInput, call.Schema, call.RepairText)
+ } else {
+ obj, err = schema.ParseAndValidate(toolInput, call.Schema)
+ }
+
+ if err == nil {
+ if !reflect.DeepEqual(obj, lastParsedObject) {
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeObject,
+ Object: obj,
+ }) {
+ return
+ }
+ lastParsedObject = obj
+ }
+ }
+
+ case fantasy.StreamPartTypeError:
+ streamErr = part.Error
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeError,
+ Error: part.Error,
+ }) {
+ return
+ }
+
+ case fantasy.StreamPartTypeFinish:
+ usage = part.Usage
+ finishReason = part.FinishReason
+
+ case fantasy.StreamPartTypeWarnings:
+ warnings = part.Warnings
+ }
+
+ if len(part.ProviderMetadata) > 0 {
+ providerMetadata = part.ProviderMetadata
+ }
+ }
+
+ if streamErr == nil && lastParsedObject != nil {
+ yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeFinish,
+ Usage: usage,
+ FinishReason: finishReason,
+ Warnings: warnings,
+ ProviderMetadata: providerMetadata,
+ })
+ } else if streamErr == nil && lastParsedObject == nil {
+ yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeError,
+ Error: &fantasy.NoObjectGeneratedError{
+ RawText: accumulated,
+ ParseError: fmt.Errorf("no valid object generated in stream"),
+ Usage: usage,
+ FinishReason: finishReason,
+ },
+ })
+ }
+ }, nil
+}
+
+// StreamWithText is a helper for providers without tool or JSON streaming support.
+// It adds the schema to the system prompt and parses the streamed text as JSON progressively.
+func StreamWithText(
+ ctx context.Context,
+ model fantasy.LanguageModel,
+ call fantasy.ObjectCall,
+) (fantasy.ObjectStreamResponse, error) {
+ jsonSchemaMap := schema.ToMap(call.Schema)
+ jsonSchemaBytes, err := json.Marshal(jsonSchemaMap)
+ if err != nil {
+ return nil, fmt.Errorf("failed to marshal schema: %w", err)
+ }
+
+ schemaInstruction := fmt.Sprintf(
+ "You must respond with valid JSON that matches this schema: %s\n"+
+ "Respond ONLY with the JSON object, no additional text or explanation.",
+ string(jsonSchemaBytes),
+ )
+
+ enhancedPrompt := make(fantasy.Prompt, 0, len(call.Prompt)+1)
+
+ hasSystem := false
+ for _, msg := range call.Prompt {
+ if msg.Role == fantasy.MessageRoleSystem {
+ hasSystem = true
+ existingText := ""
+ if len(msg.Content) > 0 {
+ if textPart, ok := msg.Content[0].(fantasy.TextPart); ok {
+ existingText = textPart.Text
+ }
+ }
+ enhancedPrompt = append(enhancedPrompt, fantasy.NewSystemMessage(existingText+"\n\n"+schemaInstruction))
+ } else {
+ enhancedPrompt = append(enhancedPrompt, msg)
+ }
+ }
+
+ if !hasSystem {
+ enhancedPrompt = append(fantasy.Prompt{fantasy.NewSystemMessage(schemaInstruction)}, call.Prompt...)
+ }
+
+ stream, err := model.Stream(ctx, fantasy.Call{
+ Prompt: enhancedPrompt,
+ MaxOutputTokens: call.MaxOutputTokens,
+ Temperature: call.Temperature,
+ TopP: call.TopP,
+ TopK: call.TopK,
+ PresencePenalty: call.PresencePenalty,
+ FrequencyPenalty: call.FrequencyPenalty,
+ ProviderOptions: call.ProviderOptions,
+ })
+ if err != nil {
+ return nil, fmt.Errorf("text-based streaming failed: %w", err)
+ }
+
+ return func(yield func(fantasy.ObjectStreamPart) bool) {
+ var accumulated string
+ var lastParsedObject any
+ var usage fantasy.Usage
+ var finishReason fantasy.FinishReason
+ var warnings []fantasy.CallWarning
+ var providerMetadata fantasy.ProviderMetadata
+ var streamErr error
+
+ for part := range stream {
+ switch part.Type {
+ case fantasy.StreamPartTypeTextDelta:
+ accumulated += part.Delta
+
+ obj, state, parseErr := schema.ParsePartialJSON(accumulated)
+
+ if state == schema.ParseStateSuccessful || state == schema.ParseStateRepaired {
+ if err := schema.ValidateAgainstSchema(obj, call.Schema); err == nil {
+ if !reflect.DeepEqual(obj, lastParsedObject) {
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeObject,
+ Object: obj,
+ }) {
+ return
+ }
+ lastParsedObject = obj
+ }
+ }
+ }
+
+ if state == schema.ParseStateFailed && call.RepairText != nil {
+ repairedText, repairErr := call.RepairText(ctx, accumulated, parseErr)
+ if repairErr == nil {
+ obj2, state2, _ := schema.ParsePartialJSON(repairedText)
+ if (state2 == schema.ParseStateSuccessful || state2 == schema.ParseStateRepaired) &&
+ schema.ValidateAgainstSchema(obj2, call.Schema) == nil {
+ if !reflect.DeepEqual(obj2, lastParsedObject) {
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeObject,
+ Object: obj2,
+ }) {
+ return
+ }
+ lastParsedObject = obj2
+ }
+ }
+ }
+ }
+
+ case fantasy.StreamPartTypeError:
+ streamErr = part.Error
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeError,
+ Error: part.Error,
+ }) {
+ return
+ }
+
+ case fantasy.StreamPartTypeFinish:
+ usage = part.Usage
+ finishReason = part.FinishReason
+
+ case fantasy.StreamPartTypeWarnings:
+ warnings = part.Warnings
+ }
+
+ if len(part.ProviderMetadata) > 0 {
+ providerMetadata = part.ProviderMetadata
+ }
+ }
+
+ if streamErr == nil && lastParsedObject != nil {
+ yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeFinish,
+ Usage: usage,
+ FinishReason: finishReason,
+ Warnings: warnings,
+ ProviderMetadata: providerMetadata,
+ })
+ } else if streamErr == nil && lastParsedObject == nil {
+ yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeError,
+ Error: &fantasy.NoObjectGeneratedError{
+ RawText: accumulated,
+ ParseError: fmt.Errorf("no valid object generated in stream"),
+ Usage: usage,
+ FinishReason: finishReason,
+ },
+ })
+ }
+ }, nil
+}
+
+func unmarshal(obj any, target any) error {
+ jsonBytes, err := json.Marshal(obj)
+ if err != nil {
+ return fmt.Errorf("failed to marshal object: %w", err)
+ }
+
+ if err := json.Unmarshal(jsonBytes, target); err != nil {
+ return fmt.Errorf("failed to unmarshal into target type: %w", err)
+ }
+
+ return nil
+}
diff --git a/internal/fantasy/provider.go b/internal/fantasy/provider.go
new file mode 100644
index 000000000..4957419b0
--- /dev/null
+++ b/internal/fantasy/provider.go
@@ -0,0 +1,11 @@
+package fantasy
+
+import (
+ "context"
+)
+
+// Provider represents a provider of language models.
+type Provider interface {
+ Name() string
+ LanguageModel(ctx context.Context, modelID string) (LanguageModel, error)
+}
diff --git a/internal/fantasy/provider_registry.go b/internal/fantasy/provider_registry.go
new file mode 100644
index 000000000..efd90446d
--- /dev/null
+++ b/internal/fantasy/provider_registry.go
@@ -0,0 +1,106 @@
+package fantasy
+
+import (
+ "encoding/json"
+ "fmt"
+ "sync"
+)
+
+// providerDataJSON is the serialized wrapper used by the registry.
+type providerDataJSON struct {
+ Type string `json:"type"`
+ Data json.RawMessage `json:"data"`
+}
+
+// UnmarshalFunc converts raw JSON into a ProviderOptionsData implementation.
+type UnmarshalFunc func([]byte) (ProviderOptionsData, error)
+
+// providerRegistry uses sync.Map for lock-free reads after initialization.
+// All registrations happen in init() functions before concurrent access.
+var providerRegistry sync.Map
+
+// RegisterProviderType registers a provider type ID with its unmarshal function.
+// Type IDs must be globally unique (e.g. "openai.options").
+// This should only be called during package initialization (init functions).
+func RegisterProviderType(typeID string, unmarshalFn UnmarshalFunc) {
+ providerRegistry.Store(typeID, unmarshalFn)
+}
+
+// unmarshalProviderData routes a typed payload to the correct constructor.
+func unmarshalProviderData(data []byte) (ProviderOptionsData, error) {
+ var pj providerDataJSON
+ if err := json.Unmarshal(data, &pj); err != nil {
+ return nil, err
+ }
+
+ val, exists := providerRegistry.Load(pj.Type)
+ if !exists {
+ return nil, fmt.Errorf("unknown provider data type: %s", pj.Type)
+ }
+
+ unmarshalFn := val.(UnmarshalFunc) //nolint:forcetypeassert // type enforced by RegisterProviderType
+ return unmarshalFn(pj.Data)
+}
+
+// unmarshalProviderDataMap is a helper for unmarshaling maps of provider data.
+func unmarshalProviderDataMap(data map[string]json.RawMessage) (map[string]ProviderOptionsData, error) {
+ result := make(map[string]ProviderOptionsData)
+ for provider, rawData := range data {
+ providerData, err := unmarshalProviderData(rawData)
+ if err != nil {
+ return nil, fmt.Errorf("failed to unmarshal provider data for %s: %w", provider, err)
+ }
+ result[provider] = providerData
+ }
+ return result, nil
+}
+
+// UnmarshalProviderOptions unmarshals a map of provider options by type.
+func UnmarshalProviderOptions(data map[string]json.RawMessage) (ProviderOptions, error) {
+ return unmarshalProviderDataMap(data)
+}
+
+// UnmarshalProviderMetadata unmarshals a map of provider metadata by type.
+func UnmarshalProviderMetadata(data map[string]json.RawMessage) (ProviderMetadata, error) {
+ return unmarshalProviderDataMap(data)
+}
+
+// MarshalProviderType marshals provider data with a type wrapper using generics.
+// To avoid infinite recursion, use the "type plain T" pattern before calling this.
+//
+// Usage in provider types:
+//
+// func (o ProviderOptions) MarshalJSON() ([]byte, error) {
+// type plain ProviderOptions
+// return fantasy.MarshalProviderType(TypeProviderOptions, plain(o))
+// }
+func MarshalProviderType[T any](typeID string, data T) ([]byte, error) {
+ rawData, err := json.Marshal(data)
+ if err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(providerDataJSON{
+ Type: typeID,
+ Data: json.RawMessage(rawData),
+ })
+}
+
+// UnmarshalProviderType unmarshals provider data without type wrapper using generics.
+// To avoid infinite recursion, unmarshal to a plain type first.
+// Note: This receives the inner 'data' field after type routing by the registry.
+//
+// Usage in provider types:
+//
+// func (o *ProviderOptions) UnmarshalJSON(data []byte) error {
+// type plain ProviderOptions
+// var p plain
+// if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+// return err
+// }
+// *o = ProviderOptions(p)
+// return nil
+// }
+func UnmarshalProviderType[T any](data []byte, target *T) error {
+ return json.Unmarshal(data, target)
+}
diff --git a/internal/fantasy/providers/anthropic/anthropic.go b/internal/fantasy/providers/anthropic/anthropic.go
new file mode 100644
index 000000000..135ffe9c5
--- /dev/null
+++ b/internal/fantasy/providers/anthropic/anthropic.go
@@ -0,0 +1,1032 @@
+// Package anthropic provides an implementation of the fantasy AI SDK for Anthropic's language models.
+package anthropic
+
+import (
+ "cmp"
+ "context"
+ "encoding/base64"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "maps"
+ "strings"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/object"
+ "github.com/aws/aws-sdk-go-v2/config"
+ "github.com/charmbracelet/anthropic-sdk-go"
+ "github.com/charmbracelet/anthropic-sdk-go/bedrock"
+ "github.com/charmbracelet/anthropic-sdk-go/option"
+ "github.com/charmbracelet/anthropic-sdk-go/packages/param"
+ "github.com/charmbracelet/anthropic-sdk-go/vertex"
+ "golang.org/x/oauth2/google"
+)
+
+const (
+ // Name is the name of the Anthropic provider.
+ Name = "anthropic"
+ // DefaultURL is the default URL for the Anthropic API.
+ DefaultURL = "https://api.anthropic.com"
+)
+
+type options struct {
+ baseURL string
+ apiKey string
+ name string
+ headers map[string]string
+ client option.HTTPClient
+
+ vertexProject string
+ vertexLocation string
+ skipAuth bool
+
+ useBedrock bool
+
+ objectMode fantasy.ObjectMode
+}
+
+type provider struct {
+ options options
+}
+
+// Option defines a function that configures Anthropic provider options.
+type Option = func(*options)
+
+// New creates a new Anthropic provider with the given options.
+func New(opts ...Option) (fantasy.Provider, error) {
+ providerOptions := options{
+ headers: map[string]string{},
+ objectMode: fantasy.ObjectModeAuto,
+ }
+ for _, o := range opts {
+ o(&providerOptions)
+ }
+
+ providerOptions.baseURL = cmp.Or(providerOptions.baseURL, DefaultURL)
+ providerOptions.name = cmp.Or(providerOptions.name, Name)
+ return &provider{options: providerOptions}, nil
+}
+
+// WithBaseURL sets the base URL for the Anthropic provider.
+func WithBaseURL(baseURL string) Option {
+ return func(o *options) {
+ o.baseURL = baseURL
+ }
+}
+
+// WithAPIKey sets the API key for the Anthropic provider.
+func WithAPIKey(apiKey string) Option {
+ return func(o *options) {
+ o.apiKey = apiKey
+ }
+}
+
+// WithVertex configures the Anthropic provider to use Vertex AI.
+func WithVertex(project, location string) Option {
+ return func(o *options) {
+ o.vertexProject = project
+ o.vertexLocation = location
+ }
+}
+
+// WithSkipAuth configures whether to skip authentication for the Anthropic provider.
+func WithSkipAuth(skip bool) Option {
+ return func(o *options) {
+ o.skipAuth = skip
+ }
+}
+
+// WithBedrock configures the Anthropic provider to use AWS Bedrock.
+func WithBedrock() Option {
+ return func(o *options) {
+ o.useBedrock = true
+ }
+}
+
+// WithName sets the name for the Anthropic provider.
+func WithName(name string) Option {
+ return func(o *options) {
+ o.name = name
+ }
+}
+
+// WithHeaders sets the headers for the Anthropic provider.
+func WithHeaders(headers map[string]string) Option {
+ return func(o *options) {
+ maps.Copy(o.headers, headers)
+ }
+}
+
+// WithHTTPClient sets the HTTP client for the Anthropic provider.
+func WithHTTPClient(client option.HTTPClient) Option {
+ return func(o *options) {
+ o.client = client
+ }
+}
+
+// WithObjectMode sets the object generation mode.
+func WithObjectMode(om fantasy.ObjectMode) Option {
+ return func(o *options) {
+ // not supported
+ if om == fantasy.ObjectModeJSON {
+ om = fantasy.ObjectModeAuto
+ }
+ o.objectMode = om
+ }
+}
+
+func (a *provider) LanguageModel(ctx context.Context, modelID string) (fantasy.LanguageModel, error) {
+ clientOptions := make([]option.RequestOption, 0, 5+len(a.options.headers))
+ clientOptions = append(clientOptions, option.WithMaxRetries(0))
+
+ if a.options.apiKey != "" && !a.options.useBedrock {
+ clientOptions = append(clientOptions, option.WithAPIKey(a.options.apiKey))
+ }
+ if a.options.baseURL != "" {
+ clientOptions = append(clientOptions, option.WithBaseURL(a.options.baseURL))
+ }
+ for key, value := range a.options.headers {
+ clientOptions = append(clientOptions, option.WithHeader(key, value))
+ }
+ if a.options.client != nil {
+ clientOptions = append(clientOptions, option.WithHTTPClient(a.options.client))
+ }
+ if a.options.vertexProject != "" && a.options.vertexLocation != "" {
+ var credentials *google.Credentials
+ if a.options.skipAuth {
+ credentials = &google.Credentials{TokenSource: &googleDummyTokenSource{}}
+ } else {
+ var err error
+ credentials, err = google.FindDefaultCredentials(ctx)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ clientOptions = append(
+ clientOptions,
+ vertex.WithCredentials(
+ ctx,
+ a.options.vertexLocation,
+ a.options.vertexProject,
+ credentials,
+ ),
+ )
+ }
+ if a.options.useBedrock {
+ modelID = bedrockPrefixModelWithRegion(modelID)
+
+ if a.options.skipAuth || a.options.apiKey != "" {
+ clientOptions = append(
+ clientOptions,
+ bedrock.WithConfig(bedrockBasicAuthConfig(a.options.apiKey)),
+ )
+ } else {
+ if cfg, err := config.LoadDefaultConfig(ctx); err == nil {
+ clientOptions = append(
+ clientOptions,
+ bedrock.WithConfig(cfg),
+ )
+ }
+ }
+ }
+ return languageModel{
+ modelID: modelID,
+ provider: a.options.name,
+ options: a.options,
+ client: anthropic.NewClient(clientOptions...),
+ }, nil
+}
+
+type languageModel struct {
+ provider string
+ modelID string
+ client anthropic.Client
+ options options
+}
+
+// Model implements fantasy.LanguageModel.
+func (a languageModel) Model() string {
+ return a.modelID
+}
+
+// Provider implements fantasy.LanguageModel.
+func (a languageModel) Provider() string {
+ return a.provider
+}
+
+func (a languageModel) prepareParams(call fantasy.Call) (*anthropic.MessageNewParams, []fantasy.CallWarning, error) {
+ params := &anthropic.MessageNewParams{}
+ providerOptions := &ProviderOptions{}
+ if v, ok := call.ProviderOptions[Name]; ok {
+ providerOptions, ok = v.(*ProviderOptions)
+ if !ok {
+ return nil, nil, &fantasy.Error{Title: "invalid argument", Message: "anthropic provider options should be *anthropic.ProviderOptions"}
+ }
+ }
+ sendReasoning := true
+ if providerOptions.SendReasoning != nil {
+ sendReasoning = *providerOptions.SendReasoning
+ }
+ systemBlocks, messages, warnings := toPrompt(call.Prompt, sendReasoning)
+
+ if call.FrequencyPenalty != nil {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "FrequencyPenalty",
+ })
+ }
+ if call.PresencePenalty != nil {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "PresencePenalty",
+ })
+ }
+
+ params.System = systemBlocks
+ params.Messages = messages
+ params.Model = anthropic.Model(a.modelID)
+ params.MaxTokens = 4096
+
+ if call.MaxOutputTokens != nil {
+ params.MaxTokens = *call.MaxOutputTokens
+ }
+
+ if call.Temperature != nil {
+ params.Temperature = param.NewOpt(*call.Temperature)
+ }
+ if call.TopK != nil {
+ params.TopK = param.NewOpt(*call.TopK)
+ }
+ if call.TopP != nil {
+ params.TopP = param.NewOpt(*call.TopP)
+ }
+
+ isThinking := false
+ var thinkingBudget int64
+ if providerOptions.Thinking != nil {
+ isThinking = true
+ thinkingBudget = providerOptions.Thinking.BudgetTokens
+ }
+ if isThinking {
+ if thinkingBudget == 0 {
+ return nil, nil, &fantasy.Error{Title: "no budget", Message: "thinking requires budget"}
+ }
+ params.Thinking = anthropic.ThinkingConfigParamOfEnabled(thinkingBudget)
+ if call.Temperature != nil {
+ params.Temperature = param.Opt[float64]{}
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "temperature",
+ Details: "temperature is not supported when thinking is enabled",
+ })
+ }
+ if call.TopP != nil {
+ params.TopP = param.Opt[float64]{}
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "TopP",
+ Details: "TopP is not supported when thinking is enabled",
+ })
+ }
+ if call.TopK != nil {
+ params.TopK = param.Opt[int64]{}
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "TopK",
+ Details: "TopK is not supported when thinking is enabled",
+ })
+ }
+ }
+
+ if len(call.Tools) > 0 {
+ disableParallelToolUse := false
+ if providerOptions.DisableParallelToolUse != nil {
+ disableParallelToolUse = *providerOptions.DisableParallelToolUse
+ }
+ tools, toolChoice, toolWarnings := a.toTools(call.Tools, call.ToolChoice, disableParallelToolUse)
+ params.Tools = tools
+ if toolChoice != nil {
+ params.ToolChoice = *toolChoice
+ }
+ warnings = append(warnings, toolWarnings...)
+ }
+
+ return params, warnings, nil
+}
+
+func (a *provider) Name() string {
+ return Name
+}
+
+// GetCacheControl extracts cache control settings from provider options.
+func GetCacheControl(providerOptions fantasy.ProviderOptions) *CacheControl {
+ if anthropicOptions, ok := providerOptions[Name]; ok {
+ if options, ok := anthropicOptions.(*ProviderCacheControlOptions); ok {
+ return &options.CacheControl
+ }
+ }
+ return nil
+}
+
+// GetReasoningMetadata extracts reasoning metadata from provider options.
+func GetReasoningMetadata(providerOptions fantasy.ProviderOptions) *ReasoningOptionMetadata {
+ if anthropicOptions, ok := providerOptions[Name]; ok {
+ if reasoning, ok := anthropicOptions.(*ReasoningOptionMetadata); ok {
+ return reasoning
+ }
+ }
+ return nil
+}
+
+type messageBlock struct {
+ Role fantasy.MessageRole
+ Messages []fantasy.Message
+}
+
+func groupIntoBlocks(prompt fantasy.Prompt) []*messageBlock {
+ var blocks []*messageBlock
+
+ var currentBlock *messageBlock
+
+ for _, msg := range prompt {
+ switch msg.Role {
+ case fantasy.MessageRoleSystem:
+ if currentBlock == nil || currentBlock.Role != fantasy.MessageRoleSystem {
+ currentBlock = &messageBlock{
+ Role: fantasy.MessageRoleSystem,
+ Messages: []fantasy.Message{},
+ }
+ blocks = append(blocks, currentBlock)
+ }
+ currentBlock.Messages = append(currentBlock.Messages, msg)
+ case fantasy.MessageRoleUser:
+ if currentBlock == nil || currentBlock.Role != fantasy.MessageRoleUser {
+ currentBlock = &messageBlock{
+ Role: fantasy.MessageRoleUser,
+ Messages: []fantasy.Message{},
+ }
+ blocks = append(blocks, currentBlock)
+ }
+ currentBlock.Messages = append(currentBlock.Messages, msg)
+ case fantasy.MessageRoleAssistant:
+ if currentBlock == nil || currentBlock.Role != fantasy.MessageRoleAssistant {
+ currentBlock = &messageBlock{
+ Role: fantasy.MessageRoleAssistant,
+ Messages: []fantasy.Message{},
+ }
+ blocks = append(blocks, currentBlock)
+ }
+ currentBlock.Messages = append(currentBlock.Messages, msg)
+ case fantasy.MessageRoleTool:
+ if currentBlock == nil || currentBlock.Role != fantasy.MessageRoleUser {
+ currentBlock = &messageBlock{
+ Role: fantasy.MessageRoleUser,
+ Messages: []fantasy.Message{},
+ }
+ blocks = append(blocks, currentBlock)
+ }
+ currentBlock.Messages = append(currentBlock.Messages, msg)
+ }
+ }
+ return blocks
+}
+
+func (a languageModel) toTools(tools []fantasy.Tool, toolChoice *fantasy.ToolChoice, disableParallelToolCalls bool) (anthropicTools []anthropic.ToolUnionParam, anthropicToolChoice *anthropic.ToolChoiceUnionParam, warnings []fantasy.CallWarning) {
+ for _, tool := range tools {
+ if tool.GetType() == fantasy.ToolTypeFunction {
+ ft, ok := tool.(fantasy.FunctionTool)
+ if !ok {
+ continue
+ }
+ required := []string{}
+ var properties any
+ if props, ok := ft.InputSchema["properties"]; ok {
+ properties = props
+ }
+ if req, ok := ft.InputSchema["required"]; ok {
+ if reqArr, ok := req.([]string); ok {
+ required = reqArr
+ }
+ }
+ cacheControl := GetCacheControl(ft.ProviderOptions)
+
+ anthropicTool := anthropic.ToolParam{
+ Name: ft.Name,
+ Description: anthropic.String(ft.Description),
+ InputSchema: anthropic.ToolInputSchemaParam{
+ Properties: properties,
+ Required: required,
+ },
+ }
+ if cacheControl != nil {
+ anthropicTool.CacheControl = anthropic.NewCacheControlEphemeralParam()
+ }
+ anthropicTools = append(anthropicTools, anthropic.ToolUnionParam{OfTool: &anthropicTool})
+ continue
+ }
+ // TODO: handle provider tool calls
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedTool,
+ Tool: tool,
+ Message: "tool is not supported",
+ })
+ }
+
+ // NOTE: Bedrock does not support this attribute.
+ var disableParallelToolUse param.Opt[bool]
+ if !a.options.useBedrock {
+ disableParallelToolUse = param.NewOpt(disableParallelToolCalls)
+ }
+
+ if toolChoice == nil {
+ if disableParallelToolCalls {
+ anthropicToolChoice = &anthropic.ToolChoiceUnionParam{
+ OfAuto: &anthropic.ToolChoiceAutoParam{
+ Type: "auto",
+ DisableParallelToolUse: disableParallelToolUse,
+ },
+ }
+ }
+ return anthropicTools, anthropicToolChoice, warnings
+ }
+
+ switch *toolChoice {
+ case fantasy.ToolChoiceAuto:
+ anthropicToolChoice = &anthropic.ToolChoiceUnionParam{
+ OfAuto: &anthropic.ToolChoiceAutoParam{
+ Type: "auto",
+ DisableParallelToolUse: disableParallelToolUse,
+ },
+ }
+ case fantasy.ToolChoiceRequired:
+ anthropicToolChoice = &anthropic.ToolChoiceUnionParam{
+ OfAny: &anthropic.ToolChoiceAnyParam{
+ Type: "any",
+ DisableParallelToolUse: disableParallelToolUse,
+ },
+ }
+ case fantasy.ToolChoiceNone:
+ return anthropicTools, anthropicToolChoice, warnings
+ default:
+ anthropicToolChoice = &anthropic.ToolChoiceUnionParam{
+ OfTool: &anthropic.ToolChoiceToolParam{
+ Type: "tool",
+ Name: string(*toolChoice),
+ DisableParallelToolUse: disableParallelToolUse,
+ },
+ }
+ }
+ return anthropicTools, anthropicToolChoice, warnings
+}
+
+func toPrompt(prompt fantasy.Prompt, sendReasoningData bool) ([]anthropic.TextBlockParam, []anthropic.MessageParam, []fantasy.CallWarning) {
+ var systemBlocks []anthropic.TextBlockParam
+ var messages []anthropic.MessageParam
+ var warnings []fantasy.CallWarning
+
+ blocks := groupIntoBlocks(prompt)
+ finishedSystemBlock := false
+ for _, block := range blocks {
+ switch block.Role {
+ case fantasy.MessageRoleSystem:
+ if finishedSystemBlock {
+ // skip multiple system messages that are separated by user/assistant messages
+ // TODO: see if we need to send error here?
+ continue
+ }
+ finishedSystemBlock = true
+ for _, msg := range block.Messages {
+ for i, part := range msg.Content {
+ isLastPart := i == len(msg.Content)-1
+ cacheControl := GetCacheControl(part.Options())
+ if cacheControl == nil && isLastPart {
+ cacheControl = GetCacheControl(msg.ProviderOptions)
+ }
+ text, ok := fantasy.AsMessagePart[fantasy.TextPart](part)
+ if !ok {
+ continue
+ }
+ textBlock := anthropic.TextBlockParam{
+ Text: text.Text,
+ }
+ if cacheControl != nil {
+ textBlock.CacheControl = anthropic.NewCacheControlEphemeralParam()
+ }
+ systemBlocks = append(systemBlocks, textBlock)
+ }
+ }
+
+ case fantasy.MessageRoleUser:
+ var anthropicContent []anthropic.ContentBlockParamUnion
+ for _, msg := range block.Messages {
+ if msg.Role == fantasy.MessageRoleUser {
+ for i, part := range msg.Content {
+ isLastPart := i == len(msg.Content)-1
+ cacheControl := GetCacheControl(part.Options())
+ if cacheControl == nil && isLastPart {
+ cacheControl = GetCacheControl(msg.ProviderOptions)
+ }
+ switch part.GetType() {
+ case fantasy.ContentTypeText:
+ text, ok := fantasy.AsMessagePart[fantasy.TextPart](part)
+ if !ok {
+ continue
+ }
+ textBlock := &anthropic.TextBlockParam{
+ Text: text.Text,
+ }
+ if cacheControl != nil {
+ textBlock.CacheControl = anthropic.NewCacheControlEphemeralParam()
+ }
+ anthropicContent = append(anthropicContent, anthropic.ContentBlockParamUnion{
+ OfText: textBlock,
+ })
+ case fantasy.ContentTypeFile:
+ file, ok := fantasy.AsMessagePart[fantasy.FilePart](part)
+ if !ok {
+ continue
+ }
+ // TODO: handle other file types
+ if !strings.HasPrefix(file.MediaType, "image/") {
+ continue
+ }
+
+ base64Encoded := base64.StdEncoding.EncodeToString(file.Data)
+ imageBlock := anthropic.NewImageBlockBase64(file.MediaType, base64Encoded)
+ if cacheControl != nil {
+ imageBlock.OfImage.CacheControl = anthropic.NewCacheControlEphemeralParam()
+ }
+ anthropicContent = append(anthropicContent, imageBlock)
+ }
+ }
+ } else if msg.Role == fantasy.MessageRoleTool {
+ for i, part := range msg.Content {
+ isLastPart := i == len(msg.Content)-1
+ cacheControl := GetCacheControl(part.Options())
+ if cacheControl == nil && isLastPart {
+ cacheControl = GetCacheControl(msg.ProviderOptions)
+ }
+ result, ok := fantasy.AsMessagePart[fantasy.ToolResultPart](part)
+ if !ok {
+ continue
+ }
+ toolResultBlock := anthropic.ToolResultBlockParam{
+ ToolUseID: result.ToolCallID,
+ }
+ switch result.Output.GetType() {
+ case fantasy.ToolResultContentTypeText:
+ content, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentText](result.Output)
+ if !ok {
+ continue
+ }
+ toolResultBlock.Content = []anthropic.ToolResultBlockParamContentUnion{
+ {
+ OfText: &anthropic.TextBlockParam{
+ Text: content.Text,
+ },
+ },
+ }
+ case fantasy.ToolResultContentTypeMedia:
+ content, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentMedia](result.Output)
+ if !ok {
+ continue
+ }
+ contentBlocks := []anthropic.ToolResultBlockParamContentUnion{
+ {
+ OfImage: anthropic.NewImageBlockBase64(content.MediaType, content.Data).OfImage,
+ },
+ }
+ if content.Text != "" {
+ contentBlocks = append(contentBlocks, anthropic.ToolResultBlockParamContentUnion{
+ OfText: &anthropic.TextBlockParam{
+ Text: content.Text,
+ },
+ })
+ }
+ toolResultBlock.Content = contentBlocks
+ case fantasy.ToolResultContentTypeError:
+ content, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentError](result.Output)
+ if !ok {
+ continue
+ }
+ toolResultBlock.Content = []anthropic.ToolResultBlockParamContentUnion{
+ {
+ OfText: &anthropic.TextBlockParam{
+ Text: content.Error.Error(),
+ },
+ },
+ }
+ toolResultBlock.IsError = param.NewOpt(true)
+ }
+ if cacheControl != nil {
+ toolResultBlock.CacheControl = anthropic.NewCacheControlEphemeralParam()
+ }
+ anthropicContent = append(anthropicContent, anthropic.ContentBlockParamUnion{
+ OfToolResult: &toolResultBlock,
+ })
+ }
+ }
+ }
+ if !hasVisibleUserContent(anthropicContent) {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "dropping empty user message (contains neither user-facing content nor tool results)",
+ })
+ continue
+ }
+ messages = append(messages, anthropic.NewUserMessage(anthropicContent...))
+ case fantasy.MessageRoleAssistant:
+ var anthropicContent []anthropic.ContentBlockParamUnion
+ for _, msg := range block.Messages {
+ for i, part := range msg.Content {
+ isLastPart := i == len(msg.Content)-1
+ cacheControl := GetCacheControl(part.Options())
+ if cacheControl == nil && isLastPart {
+ cacheControl = GetCacheControl(msg.ProviderOptions)
+ }
+ switch part.GetType() {
+ case fantasy.ContentTypeText:
+ text, ok := fantasy.AsMessagePart[fantasy.TextPart](part)
+ if !ok {
+ continue
+ }
+ textBlock := &anthropic.TextBlockParam{
+ Text: text.Text,
+ }
+ if cacheControl != nil {
+ textBlock.CacheControl = anthropic.NewCacheControlEphemeralParam()
+ }
+ anthropicContent = append(anthropicContent, anthropic.ContentBlockParamUnion{
+ OfText: textBlock,
+ })
+ case fantasy.ContentTypeReasoning:
+ reasoning, ok := fantasy.AsMessagePart[fantasy.ReasoningPart](part)
+ if !ok {
+ continue
+ }
+ if !sendReasoningData {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "sending reasoning content is disabled for this model",
+ })
+ continue
+ }
+ reasoningMetadata := GetReasoningMetadata(part.Options())
+ if reasoningMetadata == nil {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "unsupported reasoning metadata",
+ })
+ continue
+ }
+
+ if reasoningMetadata.Signature != "" {
+ anthropicContent = append(anthropicContent, anthropic.NewThinkingBlock(reasoningMetadata.Signature, reasoning.Text))
+ } else if reasoningMetadata.RedactedData != "" {
+ anthropicContent = append(anthropicContent, anthropic.NewRedactedThinkingBlock(reasoningMetadata.RedactedData))
+ } else {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "unsupported reasoning metadata",
+ })
+ continue
+ }
+ case fantasy.ContentTypeToolCall:
+ toolCall, ok := fantasy.AsMessagePart[fantasy.ToolCallPart](part)
+ if !ok {
+ continue
+ }
+ if toolCall.ProviderExecuted {
+ // TODO: implement provider executed call
+ continue
+ }
+
+ var inputMap map[string]any
+ err := json.Unmarshal([]byte(toolCall.Input), &inputMap)
+ if err != nil {
+ continue
+ }
+ toolUseBlock := anthropic.NewToolUseBlock(toolCall.ToolCallID, inputMap, toolCall.ToolName)
+ if cacheControl != nil {
+ toolUseBlock.OfToolUse.CacheControl = anthropic.NewCacheControlEphemeralParam()
+ }
+ anthropicContent = append(anthropicContent, toolUseBlock)
+ case fantasy.ContentTypeToolResult:
+ // TODO: implement provider executed tool result
+ }
+ }
+ }
+
+ if !hasVisibleAssistantContent(anthropicContent) {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "dropping empty assistant message (contains neither user-facing content nor tool calls)",
+ })
+ continue
+ }
+ messages = append(messages, anthropic.NewAssistantMessage(anthropicContent...))
+ }
+ }
+ return systemBlocks, messages, warnings
+}
+
+func hasVisibleUserContent(content []anthropic.ContentBlockParamUnion) bool {
+ for _, block := range content {
+ if block.OfText != nil || block.OfImage != nil || block.OfToolResult != nil {
+ return true
+ }
+ }
+ return false
+}
+
+func hasVisibleAssistantContent(content []anthropic.ContentBlockParamUnion) bool {
+ for _, block := range content {
+ if block.OfText != nil || block.OfToolUse != nil {
+ return true
+ }
+ }
+ return false
+}
+
+func mapFinishReason(finishReason string) fantasy.FinishReason {
+ switch finishReason {
+ case "end_turn", "pause_turn", "stop_sequence":
+ return fantasy.FinishReasonStop
+ case "max_tokens":
+ return fantasy.FinishReasonLength
+ case "tool_use":
+ return fantasy.FinishReasonToolCalls
+ default:
+ return fantasy.FinishReasonUnknown
+ }
+}
+
+// Generate implements fantasy.LanguageModel.
+func (a languageModel) Generate(ctx context.Context, call fantasy.Call) (*fantasy.Response, error) {
+ params, warnings, err := a.prepareParams(call)
+ if err != nil {
+ return nil, err
+ }
+ response, err := a.client.Messages.New(ctx, *params)
+ if err != nil {
+ return nil, toProviderErr(err)
+ }
+
+ var content []fantasy.Content
+ for _, block := range response.Content {
+ switch block.Type {
+ case "text":
+ text, ok := block.AsAny().(anthropic.TextBlock)
+ if !ok {
+ continue
+ }
+ content = append(content, fantasy.TextContent{
+ Text: text.Text,
+ })
+ case "thinking":
+ reasoning, ok := block.AsAny().(anthropic.ThinkingBlock)
+ if !ok {
+ continue
+ }
+ content = append(content, fantasy.ReasoningContent{
+ Text: reasoning.Thinking,
+ ProviderMetadata: fantasy.ProviderMetadata{
+ Name: &ReasoningOptionMetadata{
+ Signature: reasoning.Signature,
+ },
+ },
+ })
+ case "redacted_thinking":
+ reasoning, ok := block.AsAny().(anthropic.RedactedThinkingBlock)
+ if !ok {
+ continue
+ }
+ content = append(content, fantasy.ReasoningContent{
+ Text: "",
+ ProviderMetadata: fantasy.ProviderMetadata{
+ Name: &ReasoningOptionMetadata{
+ RedactedData: reasoning.Data,
+ },
+ },
+ })
+ case "tool_use":
+ toolUse, ok := block.AsAny().(anthropic.ToolUseBlock)
+ if !ok {
+ continue
+ }
+ content = append(content, fantasy.ToolCallContent{
+ ToolCallID: toolUse.ID,
+ ToolName: toolUse.Name,
+ Input: string(toolUse.Input),
+ ProviderExecuted: false,
+ })
+ }
+ }
+
+ return &fantasy.Response{
+ Content: content,
+ Usage: fantasy.Usage{
+ InputTokens: response.Usage.InputTokens,
+ OutputTokens: response.Usage.OutputTokens,
+ TotalTokens: response.Usage.InputTokens + response.Usage.OutputTokens,
+ CacheCreationTokens: response.Usage.CacheCreationInputTokens,
+ CacheReadTokens: response.Usage.CacheReadInputTokens,
+ },
+ FinishReason: mapFinishReason(string(response.StopReason)),
+ ProviderMetadata: fantasy.ProviderMetadata{},
+ Warnings: warnings,
+ }, nil
+}
+
+// Stream implements fantasy.LanguageModel.
+func (a languageModel) Stream(ctx context.Context, call fantasy.Call) (fantasy.StreamResponse, error) {
+ params, warnings, err := a.prepareParams(call)
+ if err != nil {
+ return nil, err
+ }
+
+ stream := a.client.Messages.NewStreaming(ctx, *params)
+ acc := anthropic.Message{}
+ return func(yield func(fantasy.StreamPart) bool) {
+ if len(warnings) > 0 {
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeWarnings,
+ Warnings: warnings,
+ }) {
+ return
+ }
+ }
+
+ for stream.Next() {
+ chunk := stream.Current()
+ _ = acc.Accumulate(chunk)
+ switch chunk.Type {
+ case "content_block_start":
+ contentBlockType := chunk.ContentBlock.Type
+ switch contentBlockType {
+ case "text":
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeTextStart,
+ ID: fmt.Sprintf("%d", chunk.Index),
+ }) {
+ return
+ }
+ case "thinking":
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningStart,
+ ID: fmt.Sprintf("%d", chunk.Index),
+ }) {
+ return
+ }
+ case "redacted_thinking":
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningStart,
+ ID: fmt.Sprintf("%d", chunk.Index),
+ ProviderMetadata: fantasy.ProviderMetadata{
+ Name: &ReasoningOptionMetadata{
+ RedactedData: chunk.ContentBlock.Data,
+ },
+ },
+ }) {
+ return
+ }
+ case "tool_use":
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolInputStart,
+ ID: chunk.ContentBlock.ID,
+ ToolCallName: chunk.ContentBlock.Name,
+ ToolCallInput: "",
+ }) {
+ return
+ }
+ }
+ case "content_block_stop":
+ if len(acc.Content)-1 < int(chunk.Index) {
+ continue
+ }
+ contentBlock := acc.Content[int(chunk.Index)]
+ switch contentBlock.Type {
+ case "text":
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeTextEnd,
+ ID: fmt.Sprintf("%d", chunk.Index),
+ }) {
+ return
+ }
+ case "thinking":
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: fmt.Sprintf("%d", chunk.Index),
+ }) {
+ return
+ }
+ case "tool_use":
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolInputEnd,
+ ID: contentBlock.ID,
+ }) {
+ return
+ }
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolCall,
+ ID: contentBlock.ID,
+ ToolCallName: contentBlock.Name,
+ ToolCallInput: string(contentBlock.Input),
+ }) {
+ return
+ }
+ }
+ case "content_block_delta":
+ switch chunk.Delta.Type {
+ case "text_delta":
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeTextDelta,
+ ID: fmt.Sprintf("%d", chunk.Index),
+ Delta: chunk.Delta.Text,
+ }) {
+ return
+ }
+ case "thinking_delta":
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: fmt.Sprintf("%d", chunk.Index),
+ Delta: chunk.Delta.Thinking,
+ }) {
+ return
+ }
+ case "signature_delta":
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: fmt.Sprintf("%d", chunk.Index),
+ ProviderMetadata: fantasy.ProviderMetadata{
+ Name: &ReasoningOptionMetadata{
+ Signature: chunk.Delta.Signature,
+ },
+ },
+ }) {
+ return
+ }
+ case "input_json_delta":
+ if len(acc.Content)-1 < int(chunk.Index) {
+ continue
+ }
+ contentBlock := acc.Content[int(chunk.Index)]
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolInputDelta,
+ ID: contentBlock.ID,
+ ToolCallInput: chunk.Delta.PartialJSON,
+ }) {
+ return
+ }
+ }
+ case "message_stop":
+ }
+ }
+
+ err := stream.Err()
+ if err == nil || errors.Is(err, io.EOF) {
+ yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeFinish,
+ ID: acc.ID,
+ FinishReason: mapFinishReason(string(acc.StopReason)),
+ Usage: fantasy.Usage{
+ InputTokens: acc.Usage.InputTokens,
+ OutputTokens: acc.Usage.OutputTokens,
+ TotalTokens: acc.Usage.InputTokens + acc.Usage.OutputTokens,
+ CacheCreationTokens: acc.Usage.CacheCreationInputTokens,
+ CacheReadTokens: acc.Usage.CacheReadInputTokens,
+ },
+ ProviderMetadata: fantasy.ProviderMetadata{},
+ })
+ return
+ } else { //nolint: revive
+ yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeError,
+ Error: toProviderErr(err),
+ })
+ return
+ }
+ }, nil
+}
+
+// GenerateObject implements fantasy.LanguageModel.
+func (a languageModel) GenerateObject(ctx context.Context, call fantasy.ObjectCall) (*fantasy.ObjectResponse, error) {
+ switch a.options.objectMode {
+ case fantasy.ObjectModeText:
+ return object.GenerateWithText(ctx, a, call)
+ default:
+ return object.GenerateWithTool(ctx, a, call)
+ }
+}
+
+// StreamObject implements fantasy.LanguageModel.
+func (a languageModel) StreamObject(ctx context.Context, call fantasy.ObjectCall) (fantasy.ObjectStreamResponse, error) {
+ switch a.options.objectMode {
+ case fantasy.ObjectModeText:
+ return object.StreamWithText(ctx, a, call)
+ default:
+ return object.StreamWithTool(ctx, a, call)
+ }
+}
diff --git a/internal/fantasy/providers/anthropic/anthropic_test.go b/internal/fantasy/providers/anthropic/anthropic_test.go
new file mode 100644
index 000000000..b826882c5
--- /dev/null
+++ b/internal/fantasy/providers/anthropic/anthropic_test.go
@@ -0,0 +1,343 @@
+package anthropic
+
+import (
+ "errors"
+ "testing"
+
+ "charm.land/fantasy"
+ "github.com/stretchr/testify/require"
+)
+
+func TestToPrompt_DropsEmptyMessages(t *testing.T) {
+ t.Parallel()
+
+ t.Run("should drop assistant messages with only reasoning content", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.ReasoningPart{
+ Text: "Let me think about this...",
+ ProviderOptions: fantasy.ProviderOptions{
+ Name: &ReasoningOptionMetadata{
+ Signature: "abc123",
+ },
+ },
+ },
+ },
+ },
+ }
+
+ systemBlocks, messages, warnings := toPrompt(prompt, true)
+
+ require.Empty(t, systemBlocks)
+ require.Len(t, messages, 1, "should only have user message, assistant message should be dropped")
+ require.Len(t, warnings, 1)
+ require.Equal(t, fantasy.CallWarningTypeOther, warnings[0].Type)
+ require.Contains(t, warnings[0].Message, "dropping empty assistant message")
+ require.Contains(t, warnings[0].Message, "neither user-facing content nor tool calls")
+ })
+
+ t.Run("should drop assistant reasoning when sendReasoning disabled", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.ReasoningPart{
+ Text: "Let me think about this...",
+ ProviderOptions: fantasy.ProviderOptions{
+ Name: &ReasoningOptionMetadata{
+ Signature: "def456",
+ },
+ },
+ },
+ },
+ },
+ }
+
+ systemBlocks, messages, warnings := toPrompt(prompt, false)
+
+ require.Empty(t, systemBlocks)
+ require.Len(t, messages, 1, "should only have user message, assistant message should be dropped")
+ require.Len(t, warnings, 2)
+ require.Equal(t, fantasy.CallWarningTypeOther, warnings[0].Type)
+ require.Contains(t, warnings[0].Message, "sending reasoning content is disabled")
+ require.Equal(t, fantasy.CallWarningTypeOther, warnings[1].Type)
+ require.Contains(t, warnings[1].Message, "dropping empty assistant message")
+ })
+
+ t.Run("should drop truly empty assistant messages", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{},
+ },
+ }
+
+ systemBlocks, messages, warnings := toPrompt(prompt, true)
+
+ require.Empty(t, systemBlocks)
+ require.Len(t, messages, 1, "should only have user message")
+ require.Len(t, warnings, 1)
+ require.Equal(t, fantasy.CallWarningTypeOther, warnings[0].Type)
+ require.Contains(t, warnings[0].Message, "dropping empty assistant message")
+ })
+
+ t.Run("should keep assistant messages with text content", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hi there!"},
+ },
+ },
+ }
+
+ systemBlocks, messages, warnings := toPrompt(prompt, true)
+
+ require.Empty(t, systemBlocks)
+ require.Len(t, messages, 2, "should have both user and assistant messages")
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should keep assistant messages with tool calls", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "What's the weather?"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolCallPart{
+ ToolCallID: "call_123",
+ ToolName: "get_weather",
+ Input: `{"location":"NYC"}`,
+ },
+ },
+ },
+ }
+
+ systemBlocks, messages, warnings := toPrompt(prompt, true)
+
+ require.Empty(t, systemBlocks)
+ require.Len(t, messages, 2, "should have both user and assistant messages")
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should drop assistant messages with invalid tool input", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hi"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolCallPart{
+ ToolCallID: "call_123",
+ ToolName: "get_weather",
+ Input: "{not-json",
+ },
+ },
+ },
+ }
+
+ systemBlocks, messages, warnings := toPrompt(prompt, true)
+
+ require.Empty(t, systemBlocks)
+ require.Len(t, messages, 1, "should only have user message")
+ require.Len(t, warnings, 1)
+ require.Equal(t, fantasy.CallWarningTypeOther, warnings[0].Type)
+ require.Contains(t, warnings[0].Message, "dropping empty assistant message")
+ })
+
+ t.Run("should keep assistant messages with reasoning and text", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.ReasoningPart{
+ Text: "Let me think...",
+ ProviderOptions: fantasy.ProviderOptions{
+ Name: &ReasoningOptionMetadata{
+ Signature: "abc123",
+ },
+ },
+ },
+ fantasy.TextPart{Text: "Hi there!"},
+ },
+ },
+ }
+
+ systemBlocks, messages, warnings := toPrompt(prompt, true)
+
+ require.Empty(t, systemBlocks)
+ require.Len(t, messages, 2, "should have both user and assistant messages")
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should keep user messages with image content", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ Data: []byte{0x01, 0x02, 0x03},
+ MediaType: "image/png",
+ },
+ },
+ },
+ }
+
+ systemBlocks, messages, warnings := toPrompt(prompt, true)
+
+ require.Empty(t, systemBlocks)
+ require.Len(t, messages, 1)
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should drop user messages without visible content", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ Data: []byte("not supported"),
+ MediaType: "application/pdf",
+ },
+ },
+ },
+ }
+
+ systemBlocks, messages, warnings := toPrompt(prompt, true)
+
+ require.Empty(t, systemBlocks)
+ require.Empty(t, messages)
+ require.Len(t, warnings, 1)
+ require.Equal(t, fantasy.CallWarningTypeOther, warnings[0].Type)
+ require.Contains(t, warnings[0].Message, "dropping empty user message")
+ require.Contains(t, warnings[0].Message, "neither user-facing content nor tool results")
+ })
+
+ t.Run("should keep user messages with tool results", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleTool,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolResultPart{
+ ToolCallID: "call_123",
+ Output: fantasy.ToolResultOutputContentText{Text: "done"},
+ },
+ },
+ },
+ }
+
+ systemBlocks, messages, warnings := toPrompt(prompt, true)
+
+ require.Empty(t, systemBlocks)
+ require.Len(t, messages, 1)
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should keep user messages with tool error results", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleTool,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolResultPart{
+ ToolCallID: "call_456",
+ Output: fantasy.ToolResultOutputContentError{Error: errors.New("boom")},
+ },
+ },
+ },
+ }
+
+ systemBlocks, messages, warnings := toPrompt(prompt, true)
+
+ require.Empty(t, systemBlocks)
+ require.Len(t, messages, 1)
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should keep user messages with tool media results", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleTool,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolResultPart{
+ ToolCallID: "call_789",
+ Output: fantasy.ToolResultOutputContentMedia{
+ Data: "AQID",
+ MediaType: "image/png",
+ },
+ },
+ },
+ },
+ }
+
+ systemBlocks, messages, warnings := toPrompt(prompt, true)
+
+ require.Empty(t, systemBlocks)
+ require.Len(t, messages, 1)
+ require.Empty(t, warnings)
+ })
+}
diff --git a/internal/fantasy/providers/anthropic/bedrock.go b/internal/fantasy/providers/anthropic/bedrock.go
new file mode 100644
index 000000000..8d9b94959
--- /dev/null
+++ b/internal/fantasy/providers/anthropic/bedrock.go
@@ -0,0 +1,29 @@
+package anthropic
+
+import (
+ "cmp"
+ "os"
+ "strings"
+
+ "github.com/aws/aws-sdk-go-v2/aws"
+ "github.com/aws/smithy-go/auth/bearer"
+)
+
+func bedrockBasicAuthConfig(apiKey string) aws.Config {
+ return aws.Config{
+ Region: cmp.Or(os.Getenv("AWS_REGION"), "us-east-1"),
+ BearerAuthTokenProvider: bearer.StaticTokenProvider{Token: bearer.Token{Value: apiKey}},
+ }
+}
+
+func bedrockPrefixModelWithRegion(modelID string) string {
+ region := os.Getenv("AWS_REGION")
+ if len(region) < 2 {
+ region = "us-east-1"
+ }
+ prefix := region[:2] + "."
+ if strings.HasPrefix(modelID, prefix) {
+ return modelID
+ }
+ return prefix + modelID
+}
diff --git a/internal/fantasy/providers/anthropic/error.go b/internal/fantasy/providers/anthropic/error.go
new file mode 100644
index 000000000..38393b550
--- /dev/null
+++ b/internal/fantasy/providers/anthropic/error.go
@@ -0,0 +1,39 @@
+package anthropic
+
+import (
+ "cmp"
+ "errors"
+ "net/http"
+ "strings"
+
+ "charm.land/fantasy"
+ "github.com/charmbracelet/anthropic-sdk-go"
+)
+
+func toProviderErr(err error) error {
+ var apiErr *anthropic.Error
+ if errors.As(err, &apiErr) {
+ return &fantasy.ProviderError{
+ Title: cmp.Or(fantasy.ErrorTitleForStatusCode(apiErr.StatusCode), "provider request failed"),
+ Message: apiErr.Error(),
+ Cause: apiErr,
+ URL: apiErr.Request.URL.String(),
+ StatusCode: apiErr.StatusCode,
+ RequestBody: apiErr.DumpRequest(true),
+ ResponseHeaders: toHeaderMap(apiErr.Response.Header),
+ ResponseBody: apiErr.DumpResponse(true),
+ }
+ }
+ return err
+}
+
+func toHeaderMap(in http.Header) (out map[string]string) {
+ out = make(map[string]string, len(in))
+ for k, v := range in {
+ if l := len(v); l > 0 {
+ out[k] = v[l-1]
+ in[strings.ToLower(k)] = v
+ }
+ }
+ return out
+}
diff --git a/internal/fantasy/providers/anthropic/google.go b/internal/fantasy/providers/anthropic/google.go
new file mode 100644
index 000000000..a4e4ece32
--- /dev/null
+++ b/internal/fantasy/providers/anthropic/google.go
@@ -0,0 +1,11 @@
+package anthropic
+
+import (
+ "golang.org/x/oauth2"
+)
+
+type googleDummyTokenSource struct{}
+
+func (googleDummyTokenSource) Token() (*oauth2.Token, error) {
+ return &oauth2.Token{AccessToken: "dummy-token"}, nil
+}
diff --git a/internal/fantasy/providers/anthropic/provider_options.go b/internal/fantasy/providers/anthropic/provider_options.go
new file mode 100644
index 000000000..7c426f59a
--- /dev/null
+++ b/internal/fantasy/providers/anthropic/provider_options.go
@@ -0,0 +1,151 @@
+// Package anthropic provides an implementation of the fantasy AI SDK for Anthropic's language models.
+package anthropic
+
+import (
+ "encoding/json"
+
+ "charm.land/fantasy"
+)
+
+// Global type identifiers for Anthropic-specific provider data.
+const (
+ TypeProviderOptions = Name + ".options"
+ TypeReasoningOptionMetadata = Name + ".reasoning_metadata"
+ TypeProviderCacheControl = Name + ".cache_control_options"
+)
+
+// Register Anthropic provider-specific types with the global registry.
+func init() {
+ fantasy.RegisterProviderType(TypeProviderOptions, func(data []byte) (fantasy.ProviderOptionsData, error) {
+ var v ProviderOptions
+ if err := json.Unmarshal(data, &v); err != nil {
+ return nil, err
+ }
+ return &v, nil
+ })
+ fantasy.RegisterProviderType(TypeReasoningOptionMetadata, func(data []byte) (fantasy.ProviderOptionsData, error) {
+ var v ReasoningOptionMetadata
+ if err := json.Unmarshal(data, &v); err != nil {
+ return nil, err
+ }
+ return &v, nil
+ })
+ fantasy.RegisterProviderType(TypeProviderCacheControl, func(data []byte) (fantasy.ProviderOptionsData, error) {
+ var v ProviderCacheControlOptions
+ if err := json.Unmarshal(data, &v); err != nil {
+ return nil, err
+ }
+ return &v, nil
+ })
+}
+
+// ProviderOptions represents additional options for the Anthropic provider.
+type ProviderOptions struct {
+ SendReasoning *bool `json:"send_reasoning"`
+ Thinking *ThinkingProviderOption `json:"thinking"`
+ DisableParallelToolUse *bool `json:"disable_parallel_tool_use"`
+}
+
+// Options implements the ProviderOptions interface.
+func (o *ProviderOptions) Options() {}
+
+// MarshalJSON implements custom JSON marshaling with type info for ProviderOptions.
+func (o ProviderOptions) MarshalJSON() ([]byte, error) {
+ type plain ProviderOptions
+ return fantasy.MarshalProviderType(TypeProviderOptions, plain(o))
+}
+
+// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderOptions.
+func (o *ProviderOptions) UnmarshalJSON(data []byte) error {
+ type plain ProviderOptions
+ var p plain
+ if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+ return err
+ }
+ *o = ProviderOptions(p)
+ return nil
+}
+
+// ThinkingProviderOption represents thinking options for the Anthropic provider.
+type ThinkingProviderOption struct {
+ BudgetTokens int64 `json:"budget_tokens"`
+}
+
+// ReasoningOptionMetadata represents reasoning metadata for the Anthropic provider.
+type ReasoningOptionMetadata struct {
+ Signature string `json:"signature"`
+ RedactedData string `json:"redacted_data"`
+}
+
+// Options implements the ProviderOptions interface.
+func (*ReasoningOptionMetadata) Options() {}
+
+// MarshalJSON implements custom JSON marshaling with type info for ReasoningOptionMetadata.
+func (m ReasoningOptionMetadata) MarshalJSON() ([]byte, error) {
+ type plain ReasoningOptionMetadata
+ return fantasy.MarshalProviderType(TypeReasoningOptionMetadata, plain(m))
+}
+
+// UnmarshalJSON implements custom JSON unmarshaling with type info for ReasoningOptionMetadata.
+func (m *ReasoningOptionMetadata) UnmarshalJSON(data []byte) error {
+ type plain ReasoningOptionMetadata
+ var p plain
+ if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+ return err
+ }
+ *m = ReasoningOptionMetadata(p)
+ return nil
+}
+
+// ProviderCacheControlOptions represents cache control options for the Anthropic provider.
+type ProviderCacheControlOptions struct {
+ CacheControl CacheControl `json:"cache_control"`
+}
+
+// Options implements the ProviderOptions interface.
+func (*ProviderCacheControlOptions) Options() {}
+
+// MarshalJSON implements custom JSON marshaling with type info for ProviderCacheControlOptions.
+func (o ProviderCacheControlOptions) MarshalJSON() ([]byte, error) {
+ type plain ProviderCacheControlOptions
+ return fantasy.MarshalProviderType(TypeProviderCacheControl, plain(o))
+}
+
+// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderCacheControlOptions.
+func (o *ProviderCacheControlOptions) UnmarshalJSON(data []byte) error {
+ type plain ProviderCacheControlOptions
+ var p plain
+ if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+ return err
+ }
+ *o = ProviderCacheControlOptions(p)
+ return nil
+}
+
+// CacheControl represents cache control settings for the Anthropic provider.
+type CacheControl struct {
+ Type string `json:"type"`
+}
+
+// NewProviderOptions creates new provider options for the Anthropic provider.
+func NewProviderOptions(opts *ProviderOptions) fantasy.ProviderOptions {
+ return fantasy.ProviderOptions{
+ Name: opts,
+ }
+}
+
+// NewProviderCacheControlOptions creates new cache control options for the Anthropic provider.
+func NewProviderCacheControlOptions(opts *ProviderCacheControlOptions) fantasy.ProviderOptions {
+ return fantasy.ProviderOptions{
+ Name: opts,
+ }
+}
+
+// ParseOptions parses provider options from a map for the Anthropic provider.
+func ParseOptions(data map[string]any) (*ProviderOptions, error) {
+ var options ProviderOptions
+ if err := fantasy.ParseOptions(data, &options); err != nil {
+ return nil, err
+ }
+ return &options, nil
+}
diff --git a/internal/fantasy/providers/azure/README.md b/internal/fantasy/providers/azure/README.md
new file mode 100644
index 000000000..56a4d3e2d
--- /dev/null
+++ b/internal/fantasy/providers/azure/README.md
@@ -0,0 +1,6 @@
+# Azure
+
+* Go to https://portal.azure.com/ and log in (or sign up if you haven't already)
+* Access https://ai.azure.com/
+* Create a project / resource (or use an existing one)
+* Copy and API key
diff --git a/internal/fantasy/providers/azure/azure.go b/internal/fantasy/providers/azure/azure.go
new file mode 100644
index 000000000..68adc2f7a
--- /dev/null
+++ b/internal/fantasy/providers/azure/azure.go
@@ -0,0 +1,117 @@
+// Package azure provides an implementation of the fantasy AI SDK for Azure's language models.
+package azure
+
+import (
+ "fmt"
+ "regexp"
+ "strings"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/openai"
+ "github.com/openai/openai-go/v2/azure"
+ "github.com/openai/openai-go/v2/option"
+)
+
+type options struct {
+ baseURL string
+ apiKey string
+ apiVersion string
+
+ openaiOptions []openai.Option
+}
+
+const (
+ // Name is the name of the Azure provider.
+ Name = "azure"
+ // defaultAPIVersion is the default API version for Azure.
+ defaultAPIVersion = "2025-01-01-preview"
+)
+
+// azureURLPattern matches Azure OpenAI endpoint URLs in various formats:
+// * https://resource-id.openai.azure.com;
+// * https://resource-id.openai.azure.com/;
+// * https://resource-id.cognitiveservices.azure.com;
+// * https://resource-id.services.ai.azure.com/api/projects/project-name;
+// * resource-id.openai.azure.com.
+var azureURLPattern = regexp.MustCompile(`^(?:https?://)?([a-zA-Z0-9-]+)\.(?:openai|cognitiveservices|services\.ai)\.azure\.com(?:/.*)?$`)
+
+// Option defines a function that configures Azure provider options.
+type Option = func(*options)
+
+// New creates a new Azure provider with the given options.
+func New(opts ...Option) (fantasy.Provider, error) {
+ o := options{
+ apiVersion: defaultAPIVersion,
+ }
+ for _, opt := range opts {
+ opt(&o)
+ }
+ return openai.New(
+ append(
+ o.openaiOptions,
+ openai.WithName(Name),
+ openai.WithBaseURL(o.baseURL),
+ openai.WithSDKOptions(
+ azure.WithAPIKey(o.apiKey),
+ ),
+ )...,
+ )
+}
+
+// WithBaseURL sets the base URL for the Azure provider.
+func WithBaseURL(baseURL string) Option {
+ return func(o *options) {
+ o.baseURL = parseAzureURL(baseURL)
+ }
+}
+
+// parseAzureURL extracts the resource ID from various Azure URL formats
+// and returns the standardized OpenAI-compatible endpoint URL.
+// If the URL doesn't match known Azure patterns, it returns the original URL.
+func parseAzureURL(baseURL string) string {
+ matches := azureURLPattern.FindStringSubmatch(baseURL)
+ if len(matches) >= 2 {
+ resourceID := matches[1]
+ return fmt.Sprintf("https://%s.openai.azure.com/openai/v1", resourceID)
+ }
+ // fallback to use the provided url
+ if !strings.HasPrefix(baseURL, "http://") && !strings.HasPrefix(baseURL, "https://") {
+ return "https://" + baseURL
+ }
+ return baseURL
+}
+
+// WithAPIKey sets the API key for the Azure provider.
+func WithAPIKey(apiKey string) Option {
+ return func(o *options) {
+ o.apiKey = apiKey
+ }
+}
+
+// WithHeaders sets the headers for the Azure provider.
+func WithHeaders(headers map[string]string) Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithHeaders(headers))
+ }
+}
+
+// WithAPIVersion sets the API version for the Azure provider.
+func WithAPIVersion(version string) Option {
+ return func(o *options) {
+ o.apiVersion = version
+ }
+}
+
+// WithHTTPClient sets the HTTP client for the Azure provider.
+func WithHTTPClient(client option.HTTPClient) Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithHTTPClient(client))
+ }
+}
+
+// WithUseResponsesAPI configures the provider to use the responses API for models that support it.
+func WithUseResponsesAPI() Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithUseResponsesAPI())
+ }
+}
diff --git a/internal/fantasy/providers/azure/azure_test.go b/internal/fantasy/providers/azure/azure_test.go
new file mode 100644
index 000000000..6113699d6
--- /dev/null
+++ b/internal/fantasy/providers/azure/azure_test.go
@@ -0,0 +1,98 @@
+package azure
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestParseAzureURL(t *testing.T) {
+ tests := []struct {
+ name string
+ input string
+ expected string
+ }{
+ {
+ name: "full https openai azure url",
+ input: "https://my-resource.openai.azure.com",
+ expected: "https://my-resource.openai.azure.com/openai/v1",
+ },
+ {
+ name: "full https openai azure url with trailing slash",
+ input: "https://my-resource.openai.azure.com/",
+ expected: "https://my-resource.openai.azure.com/openai/v1",
+ },
+ {
+ name: "full https cognitiveservices azure url",
+ input: "https://my-resource.cognitiveservices.azure.com",
+ expected: "https://my-resource.openai.azure.com/openai/v1",
+ },
+ {
+ name: "full https services.ai azure url with path",
+ input: "https://fantasy-playground-resource.services.ai.azure.com/api/projects/fantasy-playground",
+ expected: "https://fantasy-playground-resource.openai.azure.com/openai/v1",
+ },
+ {
+ name: "openai azure url without protocol",
+ input: "my-resource.openai.azure.com",
+ expected: "https://my-resource.openai.azure.com/openai/v1",
+ },
+ {
+ name: "cognitiveservices azure url without protocol",
+ input: "my-resource.cognitiveservices.azure.com",
+ expected: "https://my-resource.openai.azure.com/openai/v1",
+ },
+ {
+ name: "services.ai azure url without protocol",
+ input: "fantasy-playground-resource.services.ai.azure.com/api/projects/fantasy-playground",
+ expected: "https://fantasy-playground-resource.openai.azure.com/openai/v1",
+ },
+ {
+ name: "resource with hyphens",
+ input: "https://my-complex-resource-123.openai.azure.com",
+ expected: "https://my-complex-resource-123.openai.azure.com/openai/v1",
+ },
+ {
+ name: "openai azure url with trailing slash",
+ input: "https://fantasy-playground-resource.openai.azure.com/",
+ expected: "https://fantasy-playground-resource.openai.azure.com/openai/v1",
+ },
+ {
+ name: "cognitiveservices azure url with trailing slash",
+ input: "https://fantasy-playground-resource.cognitiveservices.azure.com/",
+ expected: "https://fantasy-playground-resource.openai.azure.com/openai/v1",
+ },
+ {
+ name: "malformed url - non azure domain",
+ input: "https://non.sense.com",
+ expected: "https://non.sense.com",
+ },
+ {
+ name: "malformed url - simple domain",
+ input: "example.com",
+ expected: "https://example.com",
+ },
+ {
+ name: "custom endpoint with protocol",
+ input: "https://custom-endpoint.example.com",
+ expected: "https://custom-endpoint.example.com",
+ },
+ {
+ name: "custom endpoint without protocol",
+ input: "custom-endpoint.example.com",
+ expected: "https://custom-endpoint.example.com",
+ },
+ {
+ name: "localhost",
+ input: "http://localhost:8080",
+ expected: "http://localhost:8080",
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ result := parseAzureURL(tt.input)
+ assert.Equal(t, tt.expected, result)
+ })
+ }
+}
diff --git a/internal/fantasy/providers/bedrock/README.md b/internal/fantasy/providers/bedrock/README.md
new file mode 100644
index 000000000..a24cf245d
--- /dev/null
+++ b/internal/fantasy/providers/bedrock/README.md
@@ -0,0 +1,10 @@
+# Bedrock
+
+- Install the AWS CLI
+- Log in in `aws configure`
+
+To see available models, run:
+
+```bash
+aws bedrock list-inference-profiles --region us-east-1
+```
diff --git a/internal/fantasy/providers/bedrock/bedrock.go b/internal/fantasy/providers/bedrock/bedrock.go
new file mode 100644
index 000000000..215021c18
--- /dev/null
+++ b/internal/fantasy/providers/bedrock/bedrock.go
@@ -0,0 +1,65 @@
+// Package bedrock provides an implementation of the fantasy AI SDK for AWS Bedrock's language models.
+package bedrock
+
+import (
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/anthropic"
+ "github.com/charmbracelet/anthropic-sdk-go/option"
+)
+
+type options struct {
+ skipAuth bool
+ anthropicOptions []anthropic.Option
+}
+
+const (
+ // Name is the name of the Bedrock provider.
+ Name = "bedrock"
+)
+
+// Option defines a function that configures Bedrock provider options.
+type Option = func(*options)
+
+// New creates a new Bedrock provider with the given options.
+func New(opts ...Option) (fantasy.Provider, error) {
+ var o options
+ for _, opt := range opts {
+ opt(&o)
+ }
+ return anthropic.New(
+ append(
+ o.anthropicOptions,
+ anthropic.WithName(Name),
+ anthropic.WithBedrock(),
+ anthropic.WithSkipAuth(o.skipAuth),
+ )...,
+ )
+}
+
+// WithAPIKey sets the access token for the Bedrock provider.
+func WithAPIKey(apiKey string) Option {
+ return func(o *options) {
+ o.anthropicOptions = append(o.anthropicOptions, anthropic.WithAPIKey(apiKey))
+ }
+}
+
+// WithHeaders sets the headers for the Bedrock provider.
+func WithHeaders(headers map[string]string) Option {
+ return func(o *options) {
+ o.anthropicOptions = append(o.anthropicOptions, anthropic.WithHeaders(headers))
+ }
+}
+
+// WithHTTPClient sets the HTTP client for the Bedrock provider.
+func WithHTTPClient(client option.HTTPClient) Option {
+ return func(o *options) {
+ o.anthropicOptions = append(o.anthropicOptions, anthropic.WithHTTPClient(client))
+ }
+}
+
+// WithSkipAuth configures whether to skip authentication for the Bedrock provider.
+func WithSkipAuth(skipAuth bool) Option {
+ return func(o *options) {
+ o.skipAuth = skipAuth
+ }
+}
diff --git a/internal/fantasy/providers/google/README.md b/internal/fantasy/providers/google/README.md
new file mode 100644
index 000000000..d7cc646c1
--- /dev/null
+++ b/internal/fantasy/providers/google/README.md
@@ -0,0 +1,63 @@
+# Google Provider
+
+This document describes how to get an API keys for Google Gemini and Vertex.
+
+## Gemini
+
+Simply navigate to [this page](https://aistudio.google.com/apikey) in the
+Google AI Studio and create a new API key.
+
+## Vertex
+
+### Install `gcloud`
+
+Install the `gcloud` command line tool. Install via Homebrew, Nix, or download
+it from [here](https://cloud.google.com/sdk/docs/install).
+
+```bash
+# Homebrew
+brew install --cask google-cloud-sdk
+
+# Nix
+nix-env -iA nixpkgs.google-cloud-sdk
+```
+
+### Authenticate
+
+Then authenticate with your Google account:
+
+```bash
+gcloud auth login
+```
+
+### Create And Setup Project
+
+Navigate here to create a new project if you haven't already:
+https://console.cloud.google.com/projectcreate
+
+Alternatively, you can create a new project via the command line:
+
+```bash
+gcloud projects create {YOUR_PROJECT_ID} --name="{YOUR_PROJECT_NAME}"
+```
+
+Set the project on your machine:
+
+```bash
+gcloud config set project {YOUR_PROJECT_ID}
+```
+
+Enable the Vertex AI API:
+
+```bash
+gcloud services enable aiplatform.googleapis.com
+```
+
+### Setup Env
+
+Finally, you need to run this command to ensure that libraries will be able to
+find your credentials.
+
+```bash
+gcloud auth application-default login
+```
diff --git a/internal/fantasy/providers/google/auth.go b/internal/fantasy/providers/google/auth.go
new file mode 100644
index 000000000..c993c1be1
--- /dev/null
+++ b/internal/fantasy/providers/google/auth.go
@@ -0,0 +1,15 @@
+// Package google provides an implementation of the fantasy AI SDK for Google's language models.
+package google
+
+import (
+ "context"
+
+ "cloud.google.com/go/auth"
+)
+
+type dummyTokenProvider struct{}
+
+// Token implements the auth.TokenProvider interface.
+func (dummyTokenProvider) Token(_ context.Context) (*auth.Token, error) {
+ return &auth.Token{Value: "dummy-token"}, nil
+}
diff --git a/internal/fantasy/providers/google/error.go b/internal/fantasy/providers/google/error.go
new file mode 100644
index 000000000..710cffff6
--- /dev/null
+++ b/internal/fantasy/providers/google/error.go
@@ -0,0 +1,23 @@
+package google
+
+import (
+ "cmp"
+ "errors"
+
+ "charm.land/fantasy"
+ "google.golang.org/genai"
+)
+
+func toProviderErr(err error) error {
+ var apiErr genai.APIError
+ if !errors.As(err, &apiErr) {
+ return err
+ }
+ return &fantasy.ProviderError{
+ Message: apiErr.Message,
+ Title: cmp.Or(fantasy.ErrorTitleForStatusCode(apiErr.Code), "provider request failed"),
+ Cause: err,
+ StatusCode: apiErr.Code,
+ ResponseBody: []byte(apiErr.Message),
+ }
+}
diff --git a/internal/fantasy/providers/google/google.go b/internal/fantasy/providers/google/google.go
new file mode 100644
index 000000000..de210ab26
--- /dev/null
+++ b/internal/fantasy/providers/google/google.go
@@ -0,0 +1,1431 @@
+package google
+
+import (
+ "cmp"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "maps"
+ "net/http"
+ "reflect"
+ "strings"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/object"
+ "charm.land/fantasy/providers/anthropic"
+ "charm.land/fantasy/schema"
+ "cloud.google.com/go/auth"
+ "github.com/charmbracelet/x/exp/slice"
+ "github.com/google/uuid"
+ "google.golang.org/genai"
+)
+
+// Name is the name of the Google provider.
+const Name = "google"
+
+type provider struct {
+ options options
+}
+
+// ToolCallIDFunc defines a function that generates a tool call ID.
+type ToolCallIDFunc = func() string
+
+type options struct {
+ apiKey string
+ name string
+ baseURL string
+ headers map[string]string
+ client *http.Client
+ backend genai.Backend
+ project string
+ location string
+ skipAuth bool
+ toolCallIDFunc ToolCallIDFunc
+ objectMode fantasy.ObjectMode
+}
+
+// Option defines a function that configures Google provider options.
+type Option = func(*options)
+
+// New creates a new Google provider with the given options.
+func New(opts ...Option) (fantasy.Provider, error) {
+ options := options{
+ headers: map[string]string{},
+ toolCallIDFunc: func() string {
+ return uuid.NewString()
+ },
+ }
+ for _, o := range opts {
+ o(&options)
+ }
+
+ options.name = cmp.Or(options.name, Name)
+
+ return &provider{
+ options: options,
+ }, nil
+}
+
+// WithBaseURL sets the base URL for the Google provider.
+func WithBaseURL(baseURL string) Option {
+ return func(o *options) {
+ o.baseURL = baseURL
+ }
+}
+
+// WithGeminiAPIKey sets the Gemini API key for the Google provider.
+func WithGeminiAPIKey(apiKey string) Option {
+ return func(o *options) {
+ o.backend = genai.BackendGeminiAPI
+ o.apiKey = apiKey
+ o.project = ""
+ o.location = ""
+ }
+}
+
+// WithVertex configures the Google provider to use Vertex AI.
+func WithVertex(project, location string) Option {
+ if project == "" || location == "" {
+ panic("project and location must be provided")
+ }
+ return func(o *options) {
+ o.backend = genai.BackendVertexAI
+ o.apiKey = ""
+ o.project = project
+ o.location = location
+ }
+}
+
+// WithSkipAuth configures whether to skip authentication for the Google provider.
+func WithSkipAuth(skipAuth bool) Option {
+ return func(o *options) {
+ o.skipAuth = skipAuth
+ }
+}
+
+// WithName sets the name for the Google provider.
+func WithName(name string) Option {
+ return func(o *options) {
+ o.name = name
+ }
+}
+
+// WithHeaders sets the headers for the Google provider.
+func WithHeaders(headers map[string]string) Option {
+ return func(o *options) {
+ maps.Copy(o.headers, headers)
+ }
+}
+
+// WithHTTPClient sets the HTTP client for the Google provider.
+func WithHTTPClient(client *http.Client) Option {
+ return func(o *options) {
+ o.client = client
+ }
+}
+
+// WithToolCallIDFunc sets the function that generates a tool call ID.
+func WithToolCallIDFunc(f ToolCallIDFunc) Option {
+ return func(o *options) {
+ o.toolCallIDFunc = f
+ }
+}
+
+// WithObjectMode sets the object generation mode for the Google provider.
+func WithObjectMode(om fantasy.ObjectMode) Option {
+ return func(o *options) {
+ o.objectMode = om
+ }
+}
+
+func (*provider) Name() string {
+ return Name
+}
+
+type languageModel struct {
+ provider string
+ modelID string
+ client *genai.Client
+ providerOptions options
+ objectMode fantasy.ObjectMode
+}
+
+// LanguageModel implements fantasy.Provider.
+func (a *provider) LanguageModel(ctx context.Context, modelID string) (fantasy.LanguageModel, error) {
+ if strings.Contains(modelID, "anthropic") || strings.Contains(modelID, "claude") {
+ p, err := anthropic.New(
+ anthropic.WithVertex(a.options.project, a.options.location),
+ anthropic.WithHTTPClient(a.options.client),
+ anthropic.WithSkipAuth(a.options.skipAuth),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return p.LanguageModel(ctx, modelID)
+ }
+
+ cc := &genai.ClientConfig{
+ HTTPClient: a.options.client,
+ Backend: a.options.backend,
+ APIKey: a.options.apiKey,
+ Project: a.options.project,
+ Location: a.options.location,
+ }
+ if a.options.skipAuth {
+ cc.Credentials = &auth.Credentials{TokenProvider: dummyTokenProvider{}}
+ } else if cc.Backend == genai.BackendVertexAI {
+ if err := cc.UseDefaultCredentials(); err != nil {
+ return nil, err
+ }
+ }
+
+ if a.options.baseURL != "" || len(a.options.headers) > 0 {
+ headers := http.Header{}
+ for k, v := range a.options.headers {
+ headers.Add(k, v)
+ }
+ cc.HTTPOptions = genai.HTTPOptions{
+ BaseURL: a.options.baseURL,
+ Headers: headers,
+ }
+ }
+ client, err := genai.NewClient(ctx, cc)
+ if err != nil {
+ return nil, err
+ }
+
+ objectMode := a.options.objectMode
+ if objectMode == "" {
+ objectMode = fantasy.ObjectModeAuto
+ }
+
+ return &languageModel{
+ modelID: modelID,
+ provider: a.options.name,
+ providerOptions: a.options,
+ client: client,
+ objectMode: objectMode,
+ }, nil
+}
+
+func (g languageModel) prepareParams(call fantasy.Call) (*genai.GenerateContentConfig, []*genai.Content, []fantasy.CallWarning, error) {
+ config := &genai.GenerateContentConfig{}
+
+ providerOptions := &ProviderOptions{}
+ if v, ok := call.ProviderOptions[Name]; ok {
+ providerOptions, ok = v.(*ProviderOptions)
+ if !ok {
+ return nil, nil, nil, &fantasy.Error{Title: "invalid argument", Message: "google provider options should be *google.ProviderOptions"}
+ }
+ }
+
+ systemInstructions, content, warnings := toGooglePrompt(call.Prompt)
+
+ if providerOptions.ThinkingConfig != nil {
+ if providerOptions.ThinkingConfig.IncludeThoughts != nil &&
+ *providerOptions.ThinkingConfig.IncludeThoughts &&
+ strings.HasPrefix(g.provider, "google.vertex.") {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "The 'includeThoughts' option is only supported with the Google Vertex provider " +
+ "and might not be supported or could behave unexpectedly with the current Google provider " +
+ fmt.Sprintf("(%s)", g.provider),
+ })
+ }
+
+ if providerOptions.ThinkingConfig.ThinkingBudget != nil &&
+ *providerOptions.ThinkingConfig.ThinkingBudget < 128 {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "The 'thinking_budget' option can not be under 128 and will be set to 128 by default",
+ })
+ providerOptions.ThinkingConfig.ThinkingBudget = fantasy.Opt(int64(128))
+ }
+ }
+
+ isGemmaModel := strings.HasPrefix(strings.ToLower(g.modelID), "gemma-")
+
+ if isGemmaModel && systemInstructions != nil && len(systemInstructions.Parts) > 0 {
+ if len(content) > 0 && content[0].Role == genai.RoleUser {
+ systemParts := []string{}
+ for _, sp := range systemInstructions.Parts {
+ systemParts = append(systemParts, sp.Text)
+ }
+ systemMsg := strings.Join(systemParts, "\n")
+ content[0].Parts = append([]*genai.Part{
+ {
+ Text: systemMsg + "\n\n",
+ },
+ }, content[0].Parts...)
+ systemInstructions = nil
+ }
+ }
+
+ config.SystemInstruction = systemInstructions
+
+ if call.MaxOutputTokens != nil {
+ config.MaxOutputTokens = int32(*call.MaxOutputTokens) //nolint: gosec
+ }
+
+ if call.Temperature != nil {
+ tmp := float32(*call.Temperature)
+ config.Temperature = &tmp
+ }
+ if call.TopK != nil {
+ tmp := float32(*call.TopK)
+ config.TopK = &tmp
+ }
+ if call.TopP != nil {
+ tmp := float32(*call.TopP)
+ config.TopP = &tmp
+ }
+ if call.FrequencyPenalty != nil {
+ tmp := float32(*call.FrequencyPenalty)
+ config.FrequencyPenalty = &tmp
+ }
+ if call.PresencePenalty != nil {
+ tmp := float32(*call.PresencePenalty)
+ config.PresencePenalty = &tmp
+ }
+
+ if providerOptions.ThinkingConfig != nil {
+ config.ThinkingConfig = &genai.ThinkingConfig{}
+ if providerOptions.ThinkingConfig.IncludeThoughts != nil {
+ config.ThinkingConfig.IncludeThoughts = *providerOptions.ThinkingConfig.IncludeThoughts
+ }
+ if providerOptions.ThinkingConfig.ThinkingBudget != nil {
+ tmp := int32(*providerOptions.ThinkingConfig.ThinkingBudget) //nolint: gosec
+ config.ThinkingConfig.ThinkingBudget = &tmp
+ }
+ }
+ for _, safetySetting := range providerOptions.SafetySettings {
+ config.SafetySettings = append(config.SafetySettings, &genai.SafetySetting{
+ Category: genai.HarmCategory(safetySetting.Category),
+ Threshold: genai.HarmBlockThreshold(safetySetting.Threshold),
+ })
+ }
+ if providerOptions.CachedContent != "" {
+ config.CachedContent = providerOptions.CachedContent
+ }
+
+ if len(call.Tools) > 0 {
+ tools, toolChoice, toolWarnings := toGoogleTools(call.Tools, call.ToolChoice)
+ config.ToolConfig = toolChoice
+ config.Tools = append(config.Tools, &genai.Tool{
+ FunctionDeclarations: tools,
+ })
+ warnings = append(warnings, toolWarnings...)
+ }
+
+ return config, content, warnings, nil
+}
+
+func toGooglePrompt(prompt fantasy.Prompt) (*genai.Content, []*genai.Content, []fantasy.CallWarning) { //nolint: unparam
+ var systemInstructions *genai.Content
+ var content []*genai.Content
+ var warnings []fantasy.CallWarning
+
+ finishedSystemBlock := false
+ for _, msg := range prompt {
+ switch msg.Role {
+ case fantasy.MessageRoleSystem:
+ if finishedSystemBlock {
+ // skip multiple system messages that are separated by user/assistant messages
+ // TODO: see if we need to send error here?
+ continue
+ }
+ finishedSystemBlock = true
+
+ var systemMessages []string
+ for _, part := range msg.Content {
+ text, ok := fantasy.AsMessagePart[fantasy.TextPart](part)
+ if !ok || text.Text == "" {
+ continue
+ }
+ systemMessages = append(systemMessages, text.Text)
+ }
+ if len(systemMessages) > 0 {
+ systemInstructions = &genai.Content{
+ Parts: []*genai.Part{
+ {
+ Text: strings.Join(systemMessages, "\n"),
+ },
+ },
+ }
+ }
+ case fantasy.MessageRoleUser:
+ var parts []*genai.Part
+ for _, part := range msg.Content {
+ switch part.GetType() {
+ case fantasy.ContentTypeText:
+ text, ok := fantasy.AsMessagePart[fantasy.TextPart](part)
+ if !ok || text.Text == "" {
+ continue
+ }
+ parts = append(parts, &genai.Part{
+ Text: text.Text,
+ })
+ case fantasy.ContentTypeFile:
+ file, ok := fantasy.AsMessagePart[fantasy.FilePart](part)
+ if !ok {
+ continue
+ }
+ parts = append(parts, &genai.Part{
+ InlineData: &genai.Blob{
+ Data: file.Data,
+ MIMEType: file.MediaType,
+ },
+ })
+ }
+ }
+ if len(parts) > 0 {
+ content = append(content, &genai.Content{
+ Role: genai.RoleUser,
+ Parts: parts,
+ })
+ }
+ case fantasy.MessageRoleAssistant:
+ var parts []*genai.Part
+ var currentReasoningMetadata *ReasoningMetadata
+ for _, part := range msg.Content {
+ switch part.GetType() {
+ case fantasy.ContentTypeReasoning:
+ reasoning, ok := fantasy.AsMessagePart[fantasy.ReasoningPart](part)
+ if !ok {
+ continue
+ }
+
+ metadata, ok := reasoning.ProviderOptions[Name]
+ if !ok {
+ continue
+ }
+ reasoningMetadata, ok := metadata.(*ReasoningMetadata)
+ if !ok {
+ continue
+ }
+ currentReasoningMetadata = reasoningMetadata
+ case fantasy.ContentTypeText:
+ text, ok := fantasy.AsMessagePart[fantasy.TextPart](part)
+ if !ok || text.Text == "" {
+ continue
+ }
+ geminiPart := &genai.Part{
+ Text: text.Text,
+ }
+ if currentReasoningMetadata != nil {
+ geminiPart.ThoughtSignature = []byte(currentReasoningMetadata.Signature)
+ currentReasoningMetadata = nil
+ }
+ parts = append(parts, geminiPart)
+ case fantasy.ContentTypeToolCall:
+ toolCall, ok := fantasy.AsMessagePart[fantasy.ToolCallPart](part)
+ if !ok {
+ continue
+ }
+
+ var result map[string]any
+ err := json.Unmarshal([]byte(toolCall.Input), &result)
+ if err != nil {
+ continue
+ }
+ geminiPart := &genai.Part{
+ FunctionCall: &genai.FunctionCall{
+ ID: toolCall.ToolCallID,
+ Name: toolCall.ToolName,
+ Args: result,
+ },
+ }
+ if currentReasoningMetadata != nil {
+ geminiPart.ThoughtSignature = []byte(currentReasoningMetadata.Signature)
+ currentReasoningMetadata = nil
+ }
+ parts = append(parts, geminiPart)
+ }
+ }
+ if len(parts) > 0 {
+ content = append(content, &genai.Content{
+ Role: genai.RoleModel,
+ Parts: parts,
+ })
+ }
+ case fantasy.MessageRoleTool:
+ var parts []*genai.Part
+ for _, part := range msg.Content {
+ switch part.GetType() {
+ case fantasy.ContentTypeToolResult:
+ result, ok := fantasy.AsMessagePart[fantasy.ToolResultPart](part)
+ if !ok {
+ continue
+ }
+ var toolCall fantasy.ToolCallPart
+ for _, m := range prompt {
+ if m.Role == fantasy.MessageRoleAssistant {
+ for _, content := range m.Content {
+ tc, ok := fantasy.AsMessagePart[fantasy.ToolCallPart](content)
+ if !ok {
+ continue
+ }
+ if tc.ToolCallID == result.ToolCallID {
+ toolCall = tc
+ break
+ }
+ }
+ }
+ }
+ switch result.Output.GetType() {
+ case fantasy.ToolResultContentTypeText:
+ content, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentText](result.Output)
+ if !ok {
+ continue
+ }
+ response := map[string]any{"result": content.Text}
+ parts = append(parts, &genai.Part{
+ FunctionResponse: &genai.FunctionResponse{
+ ID: result.ToolCallID,
+ Response: response,
+ Name: toolCall.ToolName,
+ },
+ })
+
+ case fantasy.ToolResultContentTypeError:
+ content, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentError](result.Output)
+ if !ok {
+ continue
+ }
+ response := map[string]any{"result": content.Error.Error()}
+ parts = append(parts, &genai.Part{
+ FunctionResponse: &genai.FunctionResponse{
+ ID: result.ToolCallID,
+ Response: response,
+ Name: toolCall.ToolName,
+ },
+ })
+ }
+ }
+ }
+ if len(parts) > 0 {
+ content = append(content, &genai.Content{
+ Role: genai.RoleUser,
+ Parts: parts,
+ })
+ }
+ default:
+ panic("unsupported message role: " + msg.Role)
+ }
+ }
+ return systemInstructions, content, warnings
+}
+
+// Generate implements fantasy.LanguageModel.
+func (g *languageModel) Generate(ctx context.Context, call fantasy.Call) (*fantasy.Response, error) {
+ config, contents, warnings, err := g.prepareParams(call)
+ if err != nil {
+ return nil, err
+ }
+
+ lastMessage, history, ok := slice.Pop(contents)
+ if !ok {
+ return nil, errors.New("no messages to send")
+ }
+
+ chat, err := g.client.Chats.Create(ctx, g.modelID, config, history)
+ if err != nil {
+ return nil, err
+ }
+
+ response, err := chat.SendMessage(ctx, depointerSlice(lastMessage.Parts)...)
+ if err != nil {
+ return nil, toProviderErr(err)
+ }
+
+ return g.mapResponse(response, warnings)
+}
+
+// Model implements fantasy.LanguageModel.
+func (g *languageModel) Model() string {
+ return g.modelID
+}
+
+// Provider implements fantasy.LanguageModel.
+func (g *languageModel) Provider() string {
+ return g.provider
+}
+
+// Stream implements fantasy.LanguageModel.
+func (g *languageModel) Stream(ctx context.Context, call fantasy.Call) (fantasy.StreamResponse, error) {
+ config, contents, warnings, err := g.prepareParams(call)
+ if err != nil {
+ return nil, err
+ }
+
+ lastMessage, history, ok := slice.Pop(contents)
+ if !ok {
+ return nil, errors.New("no messages to send")
+ }
+
+ chat, err := g.client.Chats.Create(ctx, g.modelID, config, history)
+ if err != nil {
+ return nil, err
+ }
+
+ return func(yield func(fantasy.StreamPart) bool) {
+ if len(warnings) > 0 {
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeWarnings,
+ Warnings: warnings,
+ }) {
+ return
+ }
+ }
+
+ var currentContent string
+ var toolCalls []fantasy.ToolCallContent
+ var isActiveText bool
+ var isActiveReasoning bool
+ var blockCounter int
+ var currentTextBlockID string
+ var currentReasoningBlockID string
+ var usage *fantasy.Usage
+ var lastFinishReason fantasy.FinishReason
+
+ for resp, err := range chat.SendMessageStream(ctx, depointerSlice(lastMessage.Parts)...) {
+ if err != nil {
+ yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeError,
+ Error: toProviderErr(err),
+ })
+ return
+ }
+
+ if len(resp.Candidates) > 0 && resp.Candidates[0].Content != nil {
+ for _, part := range resp.Candidates[0].Content.Parts {
+ switch {
+ case part.Text != "":
+ delta := part.Text
+ if delta != "" {
+ // Check if this is a reasoning/thought part
+ if part.Thought {
+ // End any active text block before starting reasoning
+ if isActiveText {
+ isActiveText = false
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeTextEnd,
+ ID: currentTextBlockID,
+ }) {
+ return
+ }
+ }
+
+ // Start new reasoning block if not already active
+ if !isActiveReasoning {
+ isActiveReasoning = true
+ currentReasoningBlockID = fmt.Sprintf("%d", blockCounter)
+ blockCounter++
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningStart,
+ ID: currentReasoningBlockID,
+ }) {
+ return
+ }
+ }
+
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: currentReasoningBlockID,
+ Delta: delta,
+ }) {
+ return
+ }
+ } else {
+ // Start new text block if not already active
+ if !isActiveText {
+ isActiveText = true
+ currentTextBlockID = fmt.Sprintf("%d", blockCounter)
+ blockCounter++
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeTextStart,
+ ID: currentTextBlockID,
+ }) {
+ return
+ }
+ }
+ // End any active reasoning block before starting text
+ if isActiveReasoning {
+ isActiveReasoning = false
+ metadata := &ReasoningMetadata{
+ Signature: string(part.ThoughtSignature),
+ }
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: currentReasoningBlockID,
+ ProviderMetadata: fantasy.ProviderMetadata{
+ Name: metadata,
+ },
+ }) {
+ return
+ }
+ } else if part.ThoughtSignature != nil {
+ metadata := &ReasoningMetadata{
+ Signature: string(part.ThoughtSignature),
+ }
+
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningStart,
+ ID: currentReasoningBlockID,
+ }) {
+ return
+ }
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: currentReasoningBlockID,
+ ProviderMetadata: fantasy.ProviderMetadata{
+ Name: metadata,
+ },
+ }) {
+ return
+ }
+ }
+
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeTextDelta,
+ ID: currentTextBlockID,
+ Delta: delta,
+ }) {
+ return
+ }
+ currentContent += delta
+ }
+ }
+ case part.FunctionCall != nil:
+ // End any active text or reasoning blocks
+ if isActiveText {
+ isActiveText = false
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeTextEnd,
+ ID: currentTextBlockID,
+ }) {
+ return
+ }
+ }
+ toolCallID := cmp.Or(part.FunctionCall.ID, g.providerOptions.toolCallIDFunc())
+ // End any active reasoning block before starting text
+ if isActiveReasoning {
+ isActiveReasoning = false
+ metadata := &ReasoningMetadata{
+ Signature: string(part.ThoughtSignature),
+ ToolID: toolCallID,
+ }
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: currentReasoningBlockID,
+ ProviderMetadata: fantasy.ProviderMetadata{
+ Name: metadata,
+ },
+ }) {
+ return
+ }
+ } else if part.ThoughtSignature != nil {
+ metadata := &ReasoningMetadata{
+ Signature: string(part.ThoughtSignature),
+ ToolID: toolCallID,
+ }
+
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningStart,
+ ID: currentReasoningBlockID,
+ }) {
+ return
+ }
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: currentReasoningBlockID,
+ ProviderMetadata: fantasy.ProviderMetadata{
+ Name: metadata,
+ },
+ }) {
+ return
+ }
+ }
+ args, err := json.Marshal(part.FunctionCall.Args)
+ if err != nil {
+ yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeError,
+ Error: err,
+ })
+ return
+ }
+
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolInputStart,
+ ID: toolCallID,
+ ToolCallName: part.FunctionCall.Name,
+ }) {
+ return
+ }
+
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolInputDelta,
+ ID: toolCallID,
+ Delta: string(args),
+ }) {
+ return
+ }
+
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolInputEnd,
+ ID: toolCallID,
+ }) {
+ return
+ }
+
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolCall,
+ ID: toolCallID,
+ ToolCallName: part.FunctionCall.Name,
+ ToolCallInput: string(args),
+ ProviderExecuted: false,
+ }) {
+ return
+ }
+
+ toolCalls = append(toolCalls, fantasy.ToolCallContent{
+ ToolCallID: toolCallID,
+ ToolName: part.FunctionCall.Name,
+ Input: string(args),
+ ProviderExecuted: false,
+ })
+ }
+ }
+ }
+
+ // we need to make sure that there is actual tokendata
+ if resp.UsageMetadata != nil && resp.UsageMetadata.TotalTokenCount != 0 {
+ currentUsage := mapUsage(resp.UsageMetadata)
+ // if first usage chunk
+ if usage == nil {
+ usage = ¤tUsage
+ } else {
+ usage.OutputTokens += currentUsage.OutputTokens
+ usage.ReasoningTokens += currentUsage.ReasoningTokens
+ usage.CacheReadTokens += currentUsage.CacheReadTokens
+ }
+ }
+
+ if len(resp.Candidates) > 0 && resp.Candidates[0].FinishReason != "" {
+ lastFinishReason = mapFinishReason(resp.Candidates[0].FinishReason)
+ }
+ }
+
+ // Close any open blocks before finishing
+ if isActiveText {
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeTextEnd,
+ ID: currentTextBlockID,
+ }) {
+ return
+ }
+ }
+ if isActiveReasoning {
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: currentReasoningBlockID,
+ }) {
+ return
+ }
+ }
+
+ finishReason := lastFinishReason
+ if len(toolCalls) > 0 {
+ finishReason = fantasy.FinishReasonToolCalls
+ } else if finishReason == "" {
+ finishReason = fantasy.FinishReasonStop
+ }
+
+ var finalUsage fantasy.Usage
+ if usage != nil {
+ finalUsage = *usage
+ }
+
+ yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeFinish,
+ Usage: finalUsage,
+ FinishReason: finishReason,
+ })
+ }, nil
+}
+
+// GenerateObject implements fantasy.LanguageModel.
+func (g *languageModel) GenerateObject(ctx context.Context, call fantasy.ObjectCall) (*fantasy.ObjectResponse, error) {
+ switch g.objectMode {
+ case fantasy.ObjectModeText:
+ return object.GenerateWithText(ctx, g, call)
+ case fantasy.ObjectModeTool:
+ return object.GenerateWithTool(ctx, g, call)
+ default:
+ return g.generateObjectWithJSONMode(ctx, call)
+ }
+}
+
+// StreamObject implements fantasy.LanguageModel.
+func (g *languageModel) StreamObject(ctx context.Context, call fantasy.ObjectCall) (fantasy.ObjectStreamResponse, error) {
+ switch g.objectMode {
+ case fantasy.ObjectModeTool:
+ return object.StreamWithTool(ctx, g, call)
+ case fantasy.ObjectModeText:
+ return object.StreamWithText(ctx, g, call)
+ default:
+ return g.streamObjectWithJSONMode(ctx, call)
+ }
+}
+
+func (g *languageModel) generateObjectWithJSONMode(ctx context.Context, call fantasy.ObjectCall) (*fantasy.ObjectResponse, error) {
+ // Convert our Schema to Google's JSON Schema format
+ jsonSchemaMap := schema.ToMap(call.Schema)
+
+ // Build request using prepareParams
+ fantasyCall := fantasy.Call{
+ Prompt: call.Prompt,
+ MaxOutputTokens: call.MaxOutputTokens,
+ Temperature: call.Temperature,
+ TopP: call.TopP,
+ TopK: call.TopK,
+ PresencePenalty: call.PresencePenalty,
+ FrequencyPenalty: call.FrequencyPenalty,
+ ProviderOptions: call.ProviderOptions,
+ }
+
+ config, contents, warnings, err := g.prepareParams(fantasyCall)
+ if err != nil {
+ return nil, err
+ }
+
+ // Set ResponseMIMEType and ResponseJsonSchema for structured output
+ config.ResponseMIMEType = "application/json"
+ config.ResponseJsonSchema = jsonSchemaMap
+
+ lastMessage, history, ok := slice.Pop(contents)
+ if !ok {
+ return nil, errors.New("no messages to send")
+ }
+
+ chat, err := g.client.Chats.Create(ctx, g.modelID, config, history)
+ if err != nil {
+ return nil, err
+ }
+
+ response, err := chat.SendMessage(ctx, depointerSlice(lastMessage.Parts)...)
+ if err != nil {
+ return nil, toProviderErr(err)
+ }
+
+ mappedResponse, err := g.mapResponse(response, warnings)
+ if err != nil {
+ return nil, err
+ }
+
+ jsonText := mappedResponse.Content.Text()
+ if jsonText == "" {
+ return nil, &fantasy.NoObjectGeneratedError{
+ RawText: "",
+ ParseError: fmt.Errorf("no text content in response"),
+ Usage: mappedResponse.Usage,
+ FinishReason: mappedResponse.FinishReason,
+ }
+ }
+
+ // Parse and validate
+ var obj any
+ if call.RepairText != nil {
+ obj, err = schema.ParseAndValidateWithRepair(ctx, jsonText, call.Schema, call.RepairText)
+ } else {
+ obj, err = schema.ParseAndValidate(jsonText, call.Schema)
+ }
+
+ if err != nil {
+ // Add usage info to error
+ if nogErr, ok := err.(*fantasy.NoObjectGeneratedError); ok {
+ nogErr.Usage = mappedResponse.Usage
+ nogErr.FinishReason = mappedResponse.FinishReason
+ }
+ return nil, err
+ }
+
+ return &fantasy.ObjectResponse{
+ Object: obj,
+ RawText: jsonText,
+ Usage: mappedResponse.Usage,
+ FinishReason: mappedResponse.FinishReason,
+ Warnings: warnings,
+ ProviderMetadata: mappedResponse.ProviderMetadata,
+ }, nil
+}
+
+func (g *languageModel) streamObjectWithJSONMode(ctx context.Context, call fantasy.ObjectCall) (fantasy.ObjectStreamResponse, error) {
+ // Convert our Schema to Google's JSON Schema format
+ jsonSchemaMap := schema.ToMap(call.Schema)
+
+ // Build request using prepareParams
+ fantasyCall := fantasy.Call{
+ Prompt: call.Prompt,
+ MaxOutputTokens: call.MaxOutputTokens,
+ Temperature: call.Temperature,
+ TopP: call.TopP,
+ TopK: call.TopK,
+ PresencePenalty: call.PresencePenalty,
+ FrequencyPenalty: call.FrequencyPenalty,
+ ProviderOptions: call.ProviderOptions,
+ }
+
+ config, contents, warnings, err := g.prepareParams(fantasyCall)
+ if err != nil {
+ return nil, err
+ }
+
+ // Set ResponseMIMEType and ResponseJsonSchema for structured output
+ config.ResponseMIMEType = "application/json"
+ config.ResponseJsonSchema = jsonSchemaMap
+
+ lastMessage, history, ok := slice.Pop(contents)
+ if !ok {
+ return nil, errors.New("no messages to send")
+ }
+
+ chat, err := g.client.Chats.Create(ctx, g.modelID, config, history)
+ if err != nil {
+ return nil, err
+ }
+
+ return func(yield func(fantasy.ObjectStreamPart) bool) {
+ if len(warnings) > 0 {
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeObject,
+ Warnings: warnings,
+ }) {
+ return
+ }
+ }
+
+ var accumulated string
+ var lastParsedObject any
+ var usage *fantasy.Usage
+ var lastFinishReason fantasy.FinishReason
+ var streamErr error
+
+ for resp, err := range chat.SendMessageStream(ctx, depointerSlice(lastMessage.Parts)...) {
+ if err != nil {
+ streamErr = toProviderErr(err)
+ yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeError,
+ Error: streamErr,
+ })
+ return
+ }
+
+ if len(resp.Candidates) > 0 && resp.Candidates[0].Content != nil {
+ for _, part := range resp.Candidates[0].Content.Parts {
+ if part.Text != "" && !part.Thought {
+ accumulated += part.Text
+
+ // Try to parse the accumulated text
+ obj, state, parseErr := schema.ParsePartialJSON(accumulated)
+
+ // If we successfully parsed, validate and emit
+ if state == schema.ParseStateSuccessful || state == schema.ParseStateRepaired {
+ if err := schema.ValidateAgainstSchema(obj, call.Schema); err == nil {
+ // Only emit if object is different from last
+ if !reflect.DeepEqual(obj, lastParsedObject) {
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeObject,
+ Object: obj,
+ }) {
+ return
+ }
+ lastParsedObject = obj
+ }
+ }
+ }
+
+ // If parsing failed and we have a repair function, try it
+ if state == schema.ParseStateFailed && call.RepairText != nil {
+ repairedText, repairErr := call.RepairText(ctx, accumulated, parseErr)
+ if repairErr == nil {
+ obj2, state2, _ := schema.ParsePartialJSON(repairedText)
+ if (state2 == schema.ParseStateSuccessful || state2 == schema.ParseStateRepaired) &&
+ schema.ValidateAgainstSchema(obj2, call.Schema) == nil {
+ if !reflect.DeepEqual(obj2, lastParsedObject) {
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeObject,
+ Object: obj2,
+ }) {
+ return
+ }
+ lastParsedObject = obj2
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // we need to make sure that there is actual tokendata
+ if resp.UsageMetadata != nil && resp.UsageMetadata.TotalTokenCount != 0 {
+ currentUsage := mapUsage(resp.UsageMetadata)
+ if usage == nil {
+ usage = ¤tUsage
+ } else {
+ usage.OutputTokens += currentUsage.OutputTokens
+ usage.ReasoningTokens += currentUsage.ReasoningTokens
+ usage.CacheReadTokens += currentUsage.CacheReadTokens
+ }
+ }
+
+ if len(resp.Candidates) > 0 && resp.Candidates[0].FinishReason != "" {
+ lastFinishReason = mapFinishReason(resp.Candidates[0].FinishReason)
+ }
+ }
+
+ // Final validation and emit
+ if streamErr == nil && lastParsedObject != nil {
+ finishReason := cmp.Or(lastFinishReason, fantasy.FinishReasonStop)
+
+ var finalUsage fantasy.Usage
+ if usage != nil {
+ finalUsage = *usage
+ }
+
+ yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeFinish,
+ Usage: finalUsage,
+ FinishReason: finishReason,
+ })
+ } else if streamErr == nil && lastParsedObject == nil {
+ // No object was generated
+ var finalUsage fantasy.Usage
+ if usage != nil {
+ finalUsage = *usage
+ }
+ yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeError,
+ Error: &fantasy.NoObjectGeneratedError{
+ RawText: accumulated,
+ ParseError: fmt.Errorf("no valid object generated in stream"),
+ Usage: finalUsage,
+ FinishReason: lastFinishReason,
+ },
+ })
+ }
+ }, nil
+}
+
+func toGoogleTools(tools []fantasy.Tool, toolChoice *fantasy.ToolChoice) (googleTools []*genai.FunctionDeclaration, googleToolChoice *genai.ToolConfig, warnings []fantasy.CallWarning) {
+ for _, tool := range tools {
+ if tool.GetType() == fantasy.ToolTypeFunction {
+ ft, ok := tool.(fantasy.FunctionTool)
+ if !ok {
+ continue
+ }
+
+ var required []string
+ var properties map[string]any
+ if props, ok := ft.InputSchema["properties"]; ok {
+ properties, _ = props.(map[string]any)
+ }
+ if req, ok := ft.InputSchema["required"]; ok {
+ if reqArr, ok := req.([]string); ok {
+ required = reqArr
+ }
+ }
+ declaration := &genai.FunctionDeclaration{
+ Name: ft.Name,
+ Description: ft.Description,
+ Parameters: &genai.Schema{
+ Type: genai.TypeObject,
+ Properties: convertSchemaProperties(properties),
+ Required: required,
+ },
+ }
+ googleTools = append(googleTools, declaration)
+ continue
+ }
+ // TODO: handle provider tool calls
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedTool,
+ Tool: tool,
+ Message: "tool is not supported",
+ })
+ }
+ if toolChoice == nil {
+ return googleTools, googleToolChoice, warnings
+ }
+ switch *toolChoice {
+ case fantasy.ToolChoiceAuto:
+ googleToolChoice = &genai.ToolConfig{
+ FunctionCallingConfig: &genai.FunctionCallingConfig{
+ Mode: genai.FunctionCallingConfigModeAuto,
+ },
+ }
+ case fantasy.ToolChoiceRequired:
+ googleToolChoice = &genai.ToolConfig{
+ FunctionCallingConfig: &genai.FunctionCallingConfig{
+ Mode: genai.FunctionCallingConfigModeAny,
+ },
+ }
+ case fantasy.ToolChoiceNone:
+ googleToolChoice = &genai.ToolConfig{
+ FunctionCallingConfig: &genai.FunctionCallingConfig{
+ Mode: genai.FunctionCallingConfigModeNone,
+ },
+ }
+ default:
+ googleToolChoice = &genai.ToolConfig{
+ FunctionCallingConfig: &genai.FunctionCallingConfig{
+ Mode: genai.FunctionCallingConfigModeAny,
+ AllowedFunctionNames: []string{
+ string(*toolChoice),
+ },
+ },
+ }
+ }
+ return googleTools, googleToolChoice, warnings
+}
+
+func convertSchemaProperties(parameters map[string]any) map[string]*genai.Schema {
+ properties := make(map[string]*genai.Schema)
+
+ for name, param := range parameters {
+ properties[name] = convertToSchema(param)
+ }
+
+ return properties
+}
+
+func convertToSchema(param any) *genai.Schema {
+ schema := &genai.Schema{Type: genai.TypeString}
+
+ paramMap, ok := param.(map[string]any)
+ if !ok {
+ return schema
+ }
+
+ if desc, ok := paramMap["description"].(string); ok {
+ schema.Description = desc
+ }
+
+ typeVal, hasType := paramMap["type"]
+ if !hasType {
+ return schema
+ }
+
+ typeStr, ok := typeVal.(string)
+ if !ok {
+ return schema
+ }
+
+ schema.Type = mapJSONTypeToGoogle(typeStr)
+
+ switch typeStr {
+ case "array":
+ schema.Items = processArrayItems(paramMap)
+ case "object":
+ if props, ok := paramMap["properties"].(map[string]any); ok {
+ schema.Properties = convertSchemaProperties(props)
+ }
+ }
+
+ return schema
+}
+
+func processArrayItems(paramMap map[string]any) *genai.Schema {
+ items, ok := paramMap["items"].(map[string]any)
+ if !ok {
+ return nil
+ }
+
+ return convertToSchema(items)
+}
+
+func mapJSONTypeToGoogle(jsonType string) genai.Type {
+ switch jsonType {
+ case "string":
+ return genai.TypeString
+ case "number":
+ return genai.TypeNumber
+ case "integer":
+ return genai.TypeInteger
+ case "boolean":
+ return genai.TypeBoolean
+ case "array":
+ return genai.TypeArray
+ case "object":
+ return genai.TypeObject
+ default:
+ return genai.TypeString // Default to string for unknown types
+ }
+}
+
+func (g languageModel) mapResponse(response *genai.GenerateContentResponse, warnings []fantasy.CallWarning) (*fantasy.Response, error) {
+ if len(response.Candidates) == 0 || response.Candidates[0].Content == nil {
+ return nil, errors.New("no response from model")
+ }
+
+ var (
+ content []fantasy.Content
+ finishReason fantasy.FinishReason
+ hasToolCalls bool
+ candidate = response.Candidates[0]
+ )
+
+ for _, part := range candidate.Content.Parts {
+ switch {
+ case part.Text != "":
+ if part.Thought {
+ reasoningContent := fantasy.ReasoningContent{Text: part.Text}
+ if part.ThoughtSignature != nil {
+ metadata := &ReasoningMetadata{
+ Signature: string(part.ThoughtSignature),
+ }
+ reasoningContent.ProviderMetadata = fantasy.ProviderMetadata{
+ Name: metadata,
+ }
+ }
+ content = append(content, reasoningContent)
+ } else {
+ foundReasoning := false
+ if part.ThoughtSignature != nil {
+ metadata := &ReasoningMetadata{
+ Signature: string(part.ThoughtSignature),
+ }
+ // find the last reasoning content and add the signature
+ for i := len(content) - 1; i >= 0; i-- {
+ c := content[i]
+ if c.GetType() == fantasy.ContentTypeReasoning {
+ reasoningContent, ok := fantasy.AsContentType[fantasy.ReasoningContent](c)
+ if !ok {
+ continue
+ }
+ reasoningContent.ProviderMetadata = fantasy.ProviderMetadata{
+ Name: metadata,
+ }
+ content[i] = reasoningContent
+ foundReasoning = true
+ break
+ }
+ }
+ if !foundReasoning {
+ content = append(content, fantasy.ReasoningContent{
+ ProviderMetadata: fantasy.ProviderMetadata{
+ Name: metadata,
+ },
+ })
+ }
+ }
+ content = append(content, fantasy.TextContent{Text: part.Text})
+ }
+ case part.FunctionCall != nil:
+ input, err := json.Marshal(part.FunctionCall.Args)
+ if err != nil {
+ return nil, err
+ }
+ toolCallID := cmp.Or(part.FunctionCall.ID, g.providerOptions.toolCallIDFunc())
+ foundReasoning := false
+ if part.ThoughtSignature != nil {
+ metadata := &ReasoningMetadata{
+ Signature: string(part.ThoughtSignature),
+ ToolID: toolCallID,
+ }
+ // find the last reasoning content and add the signature
+ for i := len(content) - 1; i >= 0; i-- {
+ c := content[i]
+ if c.GetType() == fantasy.ContentTypeReasoning {
+ reasoningContent, ok := fantasy.AsContentType[fantasy.ReasoningContent](c)
+ if !ok {
+ continue
+ }
+ reasoningContent.ProviderMetadata = fantasy.ProviderMetadata{
+ Name: metadata,
+ }
+ content[i] = reasoningContent
+ foundReasoning = true
+ break
+ }
+ }
+ if !foundReasoning {
+ content = append(content, fantasy.ReasoningContent{
+ ProviderMetadata: fantasy.ProviderMetadata{
+ Name: metadata,
+ },
+ })
+ }
+ }
+ content = append(content, fantasy.ToolCallContent{
+ ToolCallID: toolCallID,
+ ToolName: part.FunctionCall.Name,
+ Input: string(input),
+ ProviderExecuted: false,
+ })
+ hasToolCalls = true
+ default:
+ // Silently skip unknown part types instead of erroring
+ // This allows for forward compatibility with new part types
+ }
+ }
+
+ if hasToolCalls {
+ finishReason = fantasy.FinishReasonToolCalls
+ } else {
+ finishReason = mapFinishReason(candidate.FinishReason)
+ }
+
+ return &fantasy.Response{
+ Content: content,
+ Usage: mapUsage(response.UsageMetadata),
+ FinishReason: finishReason,
+ Warnings: warnings,
+ }, nil
+}
+
+// GetReasoningMetadata extracts reasoning metadata from provider options for google models.
+func GetReasoningMetadata(providerOptions fantasy.ProviderOptions) *ReasoningMetadata {
+ if googleOptions, ok := providerOptions[Name]; ok {
+ if reasoning, ok := googleOptions.(*ReasoningMetadata); ok {
+ return reasoning
+ }
+ }
+ return nil
+}
+
+func mapFinishReason(reason genai.FinishReason) fantasy.FinishReason {
+ switch reason {
+ case genai.FinishReasonStop:
+ return fantasy.FinishReasonStop
+ case genai.FinishReasonMaxTokens:
+ return fantasy.FinishReasonLength
+ case genai.FinishReasonSafety,
+ genai.FinishReasonBlocklist,
+ genai.FinishReasonProhibitedContent,
+ genai.FinishReasonSPII,
+ genai.FinishReasonImageSafety:
+ return fantasy.FinishReasonContentFilter
+ case genai.FinishReasonRecitation,
+ genai.FinishReasonLanguage,
+ genai.FinishReasonMalformedFunctionCall:
+ return fantasy.FinishReasonError
+ case genai.FinishReasonOther:
+ return fantasy.FinishReasonOther
+ default:
+ return fantasy.FinishReasonUnknown
+ }
+}
+
+func mapUsage(usage *genai.GenerateContentResponseUsageMetadata) fantasy.Usage {
+ return fantasy.Usage{
+ InputTokens: int64(usage.PromptTokenCount),
+ OutputTokens: int64(usage.CandidatesTokenCount),
+ TotalTokens: int64(usage.TotalTokenCount),
+ ReasoningTokens: int64(usage.ThoughtsTokenCount),
+ CacheCreationTokens: 0,
+ CacheReadTokens: int64(usage.CachedContentTokenCount),
+ }
+}
diff --git a/internal/fantasy/providers/google/provider_options.go b/internal/fantasy/providers/google/provider_options.go
new file mode 100644
index 000000000..7a0cd375c
--- /dev/null
+++ b/internal/fantasy/providers/google/provider_options.go
@@ -0,0 +1,132 @@
+// Package google provides an implementation of the fantasy AI SDK for Google's language models.
+package google
+
+import (
+ "encoding/json"
+
+ "charm.land/fantasy"
+)
+
+// Global type identifiers for Google-specific provider data.
+const (
+ TypeProviderOptions = Name + ".options"
+ TypeReasoningMetadata = Name + ".reasoning_metadata"
+)
+
+// Register Google provider-specific types with the global registry.
+func init() {
+ fantasy.RegisterProviderType(TypeProviderOptions, func(data []byte) (fantasy.ProviderOptionsData, error) {
+ var v ProviderOptions
+ if err := json.Unmarshal(data, &v); err != nil {
+ return nil, err
+ }
+ return &v, nil
+ })
+ fantasy.RegisterProviderType(TypeReasoningMetadata, func(data []byte) (fantasy.ProviderOptionsData, error) {
+ var v ReasoningMetadata
+ if err := json.Unmarshal(data, &v); err != nil {
+ return nil, err
+ }
+ return &v, nil
+ })
+}
+
+// ThinkingConfig represents thinking configuration for the Google provider.
+type ThinkingConfig struct {
+ ThinkingBudget *int64 `json:"thinking_budget"`
+ IncludeThoughts *bool `json:"include_thoughts"`
+}
+
+// ReasoningMetadata represents reasoning metadata for the Google provider.
+type ReasoningMetadata struct {
+ Signature string `json:"signature"`
+ ToolID string `json:"tool_id"`
+}
+
+// Options implements the ProviderOptionsData interface for ReasoningMetadata.
+func (m *ReasoningMetadata) Options() {}
+
+// MarshalJSON implements custom JSON marshaling with type info for ReasoningMetadata.
+func (m ReasoningMetadata) MarshalJSON() ([]byte, error) {
+ type plain ReasoningMetadata
+ return fantasy.MarshalProviderType(TypeReasoningMetadata, plain(m))
+}
+
+// UnmarshalJSON implements custom JSON unmarshaling with type info for ReasoningMetadata.
+func (m *ReasoningMetadata) UnmarshalJSON(data []byte) error {
+ type plain ReasoningMetadata
+ var p plain
+ if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+ return err
+ }
+ *m = ReasoningMetadata(p)
+ return nil
+}
+
+// SafetySetting represents safety settings for the Google provider.
+type SafetySetting struct {
+ // 'HARM_CATEGORY_UNSPECIFIED',
+ // 'HARM_CATEGORY_HATE_SPEECH',
+ // 'HARM_CATEGORY_DANGEROUS_CONTENT',
+ // 'HARM_CATEGORY_HARASSMENT',
+ // 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
+ // 'HARM_CATEGORY_CIVIC_INTEGRITY',
+ Category string `json:"category"`
+
+ // 'HARM_BLOCK_THRESHOLD_UNSPECIFIED',
+ // 'BLOCK_LOW_AND_ABOVE',
+ // 'BLOCK_MEDIUM_AND_ABOVE',
+ // 'BLOCK_ONLY_HIGH',
+ // 'BLOCK_NONE',
+ // 'OFF',
+ Threshold string `json:"threshold"`
+}
+
+// ProviderOptions represents additional options for the Google provider.
+type ProviderOptions struct {
+ ThinkingConfig *ThinkingConfig `json:"thinking_config"`
+
+ // Optional.
+ // The name of the cached content used as context to serve the prediction.
+ // Format: cachedContents/{cachedContent}
+ CachedContent string `json:"cached_content"`
+
+ // Optional. A list of unique safety settings for blocking unsafe content.
+ SafetySettings []SafetySetting `json:"safety_settings"`
+ // 'HARM_BLOCK_THRESHOLD_UNSPECIFIED',
+ // 'BLOCK_LOW_AND_ABOVE',
+ // 'BLOCK_MEDIUM_AND_ABOVE',
+ // 'BLOCK_ONLY_HIGH',
+ // 'BLOCK_NONE',
+ // 'OFF',
+ Threshold string `json:"threshold"`
+}
+
+// Options implements the ProviderOptionsData interface for ProviderOptions.
+func (o *ProviderOptions) Options() {}
+
+// MarshalJSON implements custom JSON marshaling with type info for ProviderOptions.
+func (o ProviderOptions) MarshalJSON() ([]byte, error) {
+ type plain ProviderOptions
+ return fantasy.MarshalProviderType(TypeProviderOptions, plain(o))
+}
+
+// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderOptions.
+func (o *ProviderOptions) UnmarshalJSON(data []byte) error {
+ type plain ProviderOptions
+ var p plain
+ if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+ return err
+ }
+ *o = ProviderOptions(p)
+ return nil
+}
+
+// ParseOptions parses provider options from a map for the Google provider.
+func ParseOptions(data map[string]any) (*ProviderOptions, error) {
+ var options ProviderOptions
+ if err := fantasy.ParseOptions(data, &options); err != nil {
+ return nil, err
+ }
+ return &options, nil
+}
diff --git a/internal/fantasy/providers/google/slice.go b/internal/fantasy/providers/google/slice.go
new file mode 100644
index 000000000..215355efe
--- /dev/null
+++ b/internal/fantasy/providers/google/slice.go
@@ -0,0 +1,11 @@
+package google
+
+func depointerSlice[T any](s []*T) []T {
+ result := make([]T, 0, len(s))
+ for _, v := range s {
+ if v != nil {
+ result = append(result, *v)
+ }
+ }
+ return result
+}
diff --git a/internal/fantasy/providers/openai/error.go b/internal/fantasy/providers/openai/error.go
new file mode 100644
index 000000000..fed072088
--- /dev/null
+++ b/internal/fantasy/providers/openai/error.go
@@ -0,0 +1,52 @@
+package openai
+
+import (
+ "cmp"
+ "errors"
+ "io"
+ "net/http"
+ "strings"
+
+ "charm.land/fantasy"
+ "github.com/openai/openai-go/v2"
+)
+
+func toProviderErr(err error) error {
+ var apiErr *openai.Error
+ if errors.As(err, &apiErr) {
+ return &fantasy.ProviderError{
+ Title: cmp.Or(fantasy.ErrorTitleForStatusCode(apiErr.StatusCode), "provider request failed"),
+ Message: toProviderErrMessage(apiErr),
+ Cause: apiErr,
+ URL: apiErr.Request.URL.String(),
+ StatusCode: apiErr.StatusCode,
+ RequestBody: apiErr.DumpRequest(true),
+ ResponseHeaders: toHeaderMap(apiErr.Response.Header),
+ ResponseBody: apiErr.DumpResponse(true),
+ }
+ }
+ return err
+}
+
+func toProviderErrMessage(apiErr *openai.Error) string {
+ if apiErr.Message != "" {
+ return apiErr.Message
+ }
+
+ // For some OpenAI-compatible providers, the SDK is not always able to parse
+ // the error message correctly.
+ // Fallback to returning the raw response body in such cases.
+ data, _ := io.ReadAll(apiErr.Response.Body)
+ return string(data)
+}
+
+func toHeaderMap(in http.Header) (out map[string]string) {
+ out = make(map[string]string, len(in))
+ for k, v := range in {
+ if l := len(v); l > 0 {
+ out[k] = v[l-1]
+ in[strings.ToLower(k)] = v
+ }
+ }
+ return out
+}
diff --git a/internal/fantasy/providers/openai/language_model.go b/internal/fantasy/providers/openai/language_model.go
new file mode 100644
index 000000000..9df357ac8
--- /dev/null
+++ b/internal/fantasy/providers/openai/language_model.go
@@ -0,0 +1,948 @@
+package openai
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "reflect"
+ "strings"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/object"
+ "charm.land/fantasy/schema"
+ xjson "github.com/charmbracelet/x/json"
+ "github.com/google/uuid"
+ "github.com/openai/openai-go/v2"
+ "github.com/openai/openai-go/v2/packages/param"
+ "github.com/openai/openai-go/v2/shared"
+)
+
+type languageModel struct {
+ provider string
+ modelID string
+ client openai.Client
+ objectMode fantasy.ObjectMode
+ prepareCallFunc LanguageModelPrepareCallFunc
+ mapFinishReasonFunc LanguageModelMapFinishReasonFunc
+ extraContentFunc LanguageModelExtraContentFunc
+ usageFunc LanguageModelUsageFunc
+ streamUsageFunc LanguageModelStreamUsageFunc
+ streamExtraFunc LanguageModelStreamExtraFunc
+ streamProviderMetadataFunc LanguageModelStreamProviderMetadataFunc
+ toPromptFunc LanguageModelToPromptFunc
+}
+
+// LanguageModelOption is a function that configures a languageModel.
+type LanguageModelOption = func(*languageModel)
+
+// WithLanguageModelPrepareCallFunc sets the prepare call function for the language model.
+func WithLanguageModelPrepareCallFunc(fn LanguageModelPrepareCallFunc) LanguageModelOption {
+ return func(l *languageModel) {
+ l.prepareCallFunc = fn
+ }
+}
+
+// WithLanguageModelMapFinishReasonFunc sets the map finish reason function for the language model.
+func WithLanguageModelMapFinishReasonFunc(fn LanguageModelMapFinishReasonFunc) LanguageModelOption {
+ return func(l *languageModel) {
+ l.mapFinishReasonFunc = fn
+ }
+}
+
+// WithLanguageModelExtraContentFunc sets the extra content function for the language model.
+func WithLanguageModelExtraContentFunc(fn LanguageModelExtraContentFunc) LanguageModelOption {
+ return func(l *languageModel) {
+ l.extraContentFunc = fn
+ }
+}
+
+// WithLanguageModelStreamExtraFunc sets the stream extra function for the language model.
+func WithLanguageModelStreamExtraFunc(fn LanguageModelStreamExtraFunc) LanguageModelOption {
+ return func(l *languageModel) {
+ l.streamExtraFunc = fn
+ }
+}
+
+// WithLanguageModelUsageFunc sets the usage function for the language model.
+func WithLanguageModelUsageFunc(fn LanguageModelUsageFunc) LanguageModelOption {
+ return func(l *languageModel) {
+ l.usageFunc = fn
+ }
+}
+
+// WithLanguageModelStreamUsageFunc sets the stream usage function for the language model.
+func WithLanguageModelStreamUsageFunc(fn LanguageModelStreamUsageFunc) LanguageModelOption {
+ return func(l *languageModel) {
+ l.streamUsageFunc = fn
+ }
+}
+
+// WithLanguageModelToPromptFunc sets the to prompt function for the language model.
+func WithLanguageModelToPromptFunc(fn LanguageModelToPromptFunc) LanguageModelOption {
+ return func(l *languageModel) {
+ l.toPromptFunc = fn
+ }
+}
+
+// WithLanguageModelObjectMode sets the object generation mode.
+func WithLanguageModelObjectMode(om fantasy.ObjectMode) LanguageModelOption {
+ return func(l *languageModel) {
+ // not supported
+ if om == fantasy.ObjectModeJSON {
+ om = fantasy.ObjectModeAuto
+ }
+ l.objectMode = om
+ }
+}
+
+func newLanguageModel(modelID string, provider string, client openai.Client, opts ...LanguageModelOption) languageModel {
+ model := languageModel{
+ modelID: modelID,
+ provider: provider,
+ client: client,
+ objectMode: fantasy.ObjectModeAuto,
+ prepareCallFunc: DefaultPrepareCallFunc,
+ mapFinishReasonFunc: DefaultMapFinishReasonFunc,
+ usageFunc: DefaultUsageFunc,
+ streamUsageFunc: DefaultStreamUsageFunc,
+ streamProviderMetadataFunc: DefaultStreamProviderMetadataFunc,
+ toPromptFunc: DefaultToPrompt,
+ }
+
+ for _, o := range opts {
+ o(&model)
+ }
+ return model
+}
+
+type streamToolCall struct {
+ id string
+ name string
+ arguments string
+ hasFinished bool
+}
+
+// Model implements fantasy.LanguageModel.
+func (o languageModel) Model() string {
+ return o.modelID
+}
+
+// Provider implements fantasy.LanguageModel.
+func (o languageModel) Provider() string {
+ return o.provider
+}
+
+func (o languageModel) prepareParams(call fantasy.Call) (*openai.ChatCompletionNewParams, []fantasy.CallWarning, error) {
+ params := &openai.ChatCompletionNewParams{}
+ messages, warnings := o.toPromptFunc(call.Prompt, o.provider, o.modelID)
+ if call.TopK != nil {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "top_k",
+ })
+ }
+
+ if call.MaxOutputTokens != nil {
+ params.MaxTokens = param.NewOpt(*call.MaxOutputTokens)
+ }
+ if call.Temperature != nil {
+ params.Temperature = param.NewOpt(*call.Temperature)
+ }
+ if call.TopP != nil {
+ params.TopP = param.NewOpt(*call.TopP)
+ }
+ if call.FrequencyPenalty != nil {
+ params.FrequencyPenalty = param.NewOpt(*call.FrequencyPenalty)
+ }
+ if call.PresencePenalty != nil {
+ params.PresencePenalty = param.NewOpt(*call.PresencePenalty)
+ }
+
+ if isReasoningModel(o.modelID) {
+ // remove unsupported settings for reasoning models
+ // see https://platform.openai.com/docs/guides/reasoning#limitations
+ if call.Temperature != nil {
+ params.Temperature = param.Opt[float64]{}
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "temperature",
+ Details: "temperature is not supported for reasoning models",
+ })
+ }
+ if call.TopP != nil {
+ params.TopP = param.Opt[float64]{}
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "TopP",
+ Details: "TopP is not supported for reasoning models",
+ })
+ }
+ if call.FrequencyPenalty != nil {
+ params.FrequencyPenalty = param.Opt[float64]{}
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "FrequencyPenalty",
+ Details: "FrequencyPenalty is not supported for reasoning models",
+ })
+ }
+ if call.PresencePenalty != nil {
+ params.PresencePenalty = param.Opt[float64]{}
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "PresencePenalty",
+ Details: "PresencePenalty is not supported for reasoning models",
+ })
+ }
+
+ // reasoning models use max_completion_tokens instead of max_tokens
+ if call.MaxOutputTokens != nil {
+ if !params.MaxCompletionTokens.Valid() {
+ params.MaxCompletionTokens = param.NewOpt(*call.MaxOutputTokens)
+ }
+ params.MaxTokens = param.Opt[int64]{}
+ }
+ }
+
+ // Handle search preview models
+ if isSearchPreviewModel(o.modelID) {
+ if call.Temperature != nil {
+ params.Temperature = param.Opt[float64]{}
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "temperature",
+ Details: "temperature is not supported for the search preview models and has been removed.",
+ })
+ }
+ }
+
+ optionsWarnings, err := o.prepareCallFunc(o, params, call)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if len(optionsWarnings) > 0 {
+ warnings = append(warnings, optionsWarnings...)
+ }
+
+ params.Messages = messages
+ params.Model = o.modelID
+
+ if len(call.Tools) > 0 {
+ tools, toolChoice, toolWarnings := toOpenAiTools(call.Tools, call.ToolChoice)
+ params.Tools = tools
+ if toolChoice != nil {
+ params.ToolChoice = *toolChoice
+ }
+ warnings = append(warnings, toolWarnings...)
+ }
+ return params, warnings, nil
+}
+
+// Generate implements fantasy.LanguageModel.
+func (o languageModel) Generate(ctx context.Context, call fantasy.Call) (*fantasy.Response, error) {
+ params, warnings, err := o.prepareParams(call)
+ if err != nil {
+ return nil, err
+ }
+ response, err := o.client.Chat.Completions.New(ctx, *params)
+ if err != nil {
+ return nil, toProviderErr(err)
+ }
+
+ if len(response.Choices) == 0 {
+ return nil, &fantasy.Error{Title: "no response", Message: "no response generated"}
+ }
+ choice := response.Choices[0]
+ content := make([]fantasy.Content, 0, 1+len(choice.Message.ToolCalls)+len(choice.Message.Annotations))
+ text := choice.Message.Content
+ if text != "" {
+ content = append(content, fantasy.TextContent{
+ Text: text,
+ })
+ }
+ if o.extraContentFunc != nil {
+ extraContent := o.extraContentFunc(choice)
+ content = append(content, extraContent...)
+ }
+ for _, tc := range choice.Message.ToolCalls {
+ toolCallID := tc.ID
+ content = append(content, fantasy.ToolCallContent{
+ ProviderExecuted: false,
+ ToolCallID: toolCallID,
+ ToolName: tc.Function.Name,
+ Input: tc.Function.Arguments,
+ })
+ }
+ for _, annotation := range choice.Message.Annotations {
+ if annotation.Type == "url_citation" {
+ content = append(content, fantasy.SourceContent{
+ SourceType: fantasy.SourceTypeURL,
+ ID: uuid.NewString(),
+ URL: annotation.URLCitation.URL,
+ Title: annotation.URLCitation.Title,
+ })
+ }
+ }
+
+ usage, providerMetadata := o.usageFunc(*response)
+
+ mappedFinishReason := o.mapFinishReasonFunc(choice.FinishReason)
+ if len(choice.Message.ToolCalls) > 0 {
+ mappedFinishReason = fantasy.FinishReasonToolCalls
+ }
+ return &fantasy.Response{
+ Content: content,
+ Usage: usage,
+ FinishReason: mappedFinishReason,
+ ProviderMetadata: fantasy.ProviderMetadata{
+ Name: providerMetadata,
+ },
+ Warnings: warnings,
+ }, nil
+}
+
+// Stream implements fantasy.LanguageModel.
+func (o languageModel) Stream(ctx context.Context, call fantasy.Call) (fantasy.StreamResponse, error) {
+ params, warnings, err := o.prepareParams(call)
+ if err != nil {
+ return nil, err
+ }
+
+ params.StreamOptions = openai.ChatCompletionStreamOptionsParam{
+ IncludeUsage: openai.Bool(true),
+ }
+
+ stream := o.client.Chat.Completions.NewStreaming(ctx, *params)
+ isActiveText := false
+ toolCalls := make(map[int64]streamToolCall)
+
+ providerMetadata := fantasy.ProviderMetadata{
+ Name: &ProviderMetadata{},
+ }
+ acc := openai.ChatCompletionAccumulator{}
+ extraContext := make(map[string]any)
+ var usage fantasy.Usage
+ var finishReason string
+ return func(yield func(fantasy.StreamPart) bool) {
+ if len(warnings) > 0 {
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeWarnings,
+ Warnings: warnings,
+ }) {
+ return
+ }
+ }
+ for stream.Next() {
+ chunk := stream.Current()
+ acc.AddChunk(chunk)
+ usage, providerMetadata = o.streamUsageFunc(chunk, extraContext, providerMetadata)
+ if len(chunk.Choices) == 0 {
+ continue
+ }
+ for _, choice := range chunk.Choices {
+ if choice.FinishReason != "" {
+ finishReason = choice.FinishReason
+ }
+ switch {
+ case choice.Delta.Content != "":
+ if !isActiveText {
+ isActiveText = true
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeTextStart,
+ ID: "0",
+ }) {
+ return
+ }
+ }
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeTextDelta,
+ ID: "0",
+ Delta: choice.Delta.Content,
+ }) {
+ return
+ }
+ case len(choice.Delta.ToolCalls) > 0:
+ if isActiveText {
+ isActiveText = false
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeTextEnd,
+ ID: "0",
+ }) {
+ return
+ }
+ }
+
+ for _, toolCallDelta := range choice.Delta.ToolCalls {
+ if existingToolCall, ok := toolCalls[toolCallDelta.Index]; ok {
+ if existingToolCall.hasFinished {
+ continue
+ }
+ if toolCallDelta.Function.Arguments != "" {
+ existingToolCall.arguments += toolCallDelta.Function.Arguments
+ }
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolInputDelta,
+ ID: existingToolCall.id,
+ Delta: toolCallDelta.Function.Arguments,
+ }) {
+ return
+ }
+ toolCalls[toolCallDelta.Index] = existingToolCall
+ if xjson.IsValid(existingToolCall.arguments) {
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolInputEnd,
+ ID: existingToolCall.id,
+ }) {
+ return
+ }
+
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolCall,
+ ID: existingToolCall.id,
+ ToolCallName: existingToolCall.name,
+ ToolCallInput: existingToolCall.arguments,
+ }) {
+ return
+ }
+ existingToolCall.hasFinished = true
+ toolCalls[toolCallDelta.Index] = existingToolCall
+ }
+ } else {
+ var err error
+ if toolCallDelta.Type != "function" {
+ err = &fantasy.Error{Title: "invalid provider response", Message: "expected 'function' type."}
+ }
+ if toolCallDelta.ID == "" {
+ err = &fantasy.Error{Title: "invalid provider response", Message: "expected 'id' to be a string."}
+ }
+ if toolCallDelta.Function.Name == "" {
+ err = &fantasy.Error{Title: "invalid provider response", Message: "expected 'function.name' to be a string."}
+ }
+ if err != nil {
+ yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeError,
+ Error: toProviderErr(stream.Err()),
+ })
+ return
+ }
+
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolInputStart,
+ ID: toolCallDelta.ID,
+ ToolCallName: toolCallDelta.Function.Name,
+ }) {
+ return
+ }
+ toolCalls[toolCallDelta.Index] = streamToolCall{
+ id: toolCallDelta.ID,
+ name: toolCallDelta.Function.Name,
+ arguments: toolCallDelta.Function.Arguments,
+ }
+
+ exTc := toolCalls[toolCallDelta.Index]
+ if exTc.arguments != "" {
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolInputDelta,
+ ID: exTc.id,
+ Delta: exTc.arguments,
+ }) {
+ return
+ }
+ if xjson.IsValid(toolCalls[toolCallDelta.Index].arguments) {
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolInputEnd,
+ ID: toolCallDelta.ID,
+ }) {
+ return
+ }
+
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolCall,
+ ID: exTc.id,
+ ToolCallName: exTc.name,
+ ToolCallInput: exTc.arguments,
+ }) {
+ return
+ }
+ exTc.hasFinished = true
+ toolCalls[toolCallDelta.Index] = exTc
+ }
+ }
+ continue
+ }
+ }
+ }
+
+ if o.streamExtraFunc != nil {
+ updatedContext, shouldContinue := o.streamExtraFunc(chunk, yield, extraContext)
+ if !shouldContinue {
+ return
+ }
+ extraContext = updatedContext
+ }
+ }
+
+ for _, choice := range chunk.Choices {
+ if annotations := parseAnnotationsFromDelta(choice.Delta); len(annotations) > 0 {
+ for _, annotation := range annotations {
+ if annotation.Type == "url_citation" {
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeSource,
+ ID: uuid.NewString(),
+ SourceType: fantasy.SourceTypeURL,
+ URL: annotation.URLCitation.URL,
+ Title: annotation.URLCitation.Title,
+ }) {
+ return
+ }
+ }
+ }
+ }
+ }
+ }
+ err := stream.Err()
+ if err == nil || errors.Is(err, io.EOF) {
+ if isActiveText {
+ isActiveText = false
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeTextEnd,
+ ID: "0",
+ }) {
+ return
+ }
+ }
+
+ if len(acc.Choices) > 0 {
+ choice := acc.Choices[0]
+ providerMetadata = o.streamProviderMetadataFunc(choice, providerMetadata)
+
+ for _, annotation := range choice.Message.Annotations {
+ if annotation.Type == "url_citation" {
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeSource,
+ ID: acc.ID,
+ SourceType: fantasy.SourceTypeURL,
+ URL: annotation.URLCitation.URL,
+ Title: annotation.URLCitation.Title,
+ }) {
+ return
+ }
+ }
+ }
+ }
+ mappedFinishReason := o.mapFinishReasonFunc(finishReason)
+ if len(acc.Choices) > 0 {
+ choice := acc.Choices[0]
+ if len(choice.Message.ToolCalls) > 0 {
+ mappedFinishReason = fantasy.FinishReasonToolCalls
+ }
+ }
+ yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeFinish,
+ Usage: usage,
+ FinishReason: mappedFinishReason,
+ ProviderMetadata: providerMetadata,
+ })
+ return
+ } else { //nolint: revive
+ yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeError,
+ Error: toProviderErr(err),
+ })
+ return
+ }
+ }, nil
+}
+
+func isReasoningModel(modelID string) bool {
+ return strings.HasPrefix(modelID, "o1") || strings.Contains(modelID, "-o1") ||
+ strings.HasPrefix(modelID, "o3") || strings.Contains(modelID, "-o3") ||
+ strings.HasPrefix(modelID, "o4") || strings.Contains(modelID, "-o4") ||
+ strings.HasPrefix(modelID, "oss") || strings.Contains(modelID, "-oss") ||
+ strings.Contains(modelID, "gpt-5") || strings.Contains(modelID, "gpt-5-chat")
+}
+
+func isSearchPreviewModel(modelID string) bool {
+ return strings.Contains(modelID, "search-preview")
+}
+
+func supportsFlexProcessing(modelID string) bool {
+ return strings.HasPrefix(modelID, "o3") || strings.Contains(modelID, "-o3") ||
+ strings.Contains(modelID, "o4-mini") || strings.Contains(modelID, "gpt-5")
+}
+
+func supportsPriorityProcessing(modelID string) bool {
+ return strings.Contains(modelID, "gpt-4") || strings.Contains(modelID, "gpt-5") ||
+ strings.Contains(modelID, "gpt-5-mini") || strings.HasPrefix(modelID, "o3") ||
+ strings.Contains(modelID, "-o3") || strings.Contains(modelID, "o4-mini")
+}
+
+func toOpenAiTools(tools []fantasy.Tool, toolChoice *fantasy.ToolChoice) (openAiTools []openai.ChatCompletionToolUnionParam, openAiToolChoice *openai.ChatCompletionToolChoiceOptionUnionParam, warnings []fantasy.CallWarning) {
+ for _, tool := range tools {
+ if tool.GetType() == fantasy.ToolTypeFunction {
+ ft, ok := tool.(fantasy.FunctionTool)
+ if !ok {
+ continue
+ }
+ openAiTools = append(openAiTools, openai.ChatCompletionToolUnionParam{
+ OfFunction: &openai.ChatCompletionFunctionToolParam{
+ Function: shared.FunctionDefinitionParam{
+ Name: ft.Name,
+ Description: param.NewOpt(ft.Description),
+ Parameters: openai.FunctionParameters(ft.InputSchema),
+ Strict: param.NewOpt(false),
+ },
+ Type: "function",
+ },
+ })
+ continue
+ }
+
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedTool,
+ Tool: tool,
+ Message: "tool is not supported",
+ })
+ }
+ if toolChoice == nil {
+ return openAiTools, openAiToolChoice, warnings
+ }
+
+ switch *toolChoice {
+ case fantasy.ToolChoiceAuto:
+ openAiToolChoice = &openai.ChatCompletionToolChoiceOptionUnionParam{
+ OfAuto: param.NewOpt("auto"),
+ }
+ case fantasy.ToolChoiceNone:
+ openAiToolChoice = &openai.ChatCompletionToolChoiceOptionUnionParam{
+ OfAuto: param.NewOpt("none"),
+ }
+ case fantasy.ToolChoiceRequired:
+ openAiToolChoice = &openai.ChatCompletionToolChoiceOptionUnionParam{
+ OfAuto: param.NewOpt("required"),
+ }
+ default:
+ openAiToolChoice = &openai.ChatCompletionToolChoiceOptionUnionParam{
+ OfFunctionToolChoice: &openai.ChatCompletionNamedToolChoiceParam{
+ Type: "function",
+ Function: openai.ChatCompletionNamedToolChoiceFunctionParam{
+ Name: string(*toolChoice),
+ },
+ },
+ }
+ }
+ return openAiTools, openAiToolChoice, warnings
+}
+
+// parseAnnotationsFromDelta parses annotations from the raw JSON of a delta.
+func parseAnnotationsFromDelta(delta openai.ChatCompletionChunkChoiceDelta) []openai.ChatCompletionMessageAnnotation {
+ var annotations []openai.ChatCompletionMessageAnnotation
+
+ // Parse the raw JSON to extract annotations
+ var deltaData map[string]any
+ if err := json.Unmarshal([]byte(delta.RawJSON()), &deltaData); err != nil {
+ return annotations
+ }
+
+ // Check if annotations exist in the delta
+ if annotationsData, ok := deltaData["annotations"].([]any); ok {
+ for _, annotationData := range annotationsData {
+ if annotationMap, ok := annotationData.(map[string]any); ok {
+ if annotationType, ok := annotationMap["type"].(string); ok && annotationType == "url_citation" {
+ if urlCitationData, ok := annotationMap["url_citation"].(map[string]any); ok {
+ url, urlOk := urlCitationData["url"].(string)
+ title, titleOk := urlCitationData["title"].(string)
+ if urlOk && titleOk {
+ annotation := openai.ChatCompletionMessageAnnotation{
+ Type: "url_citation",
+ URLCitation: openai.ChatCompletionMessageAnnotationURLCitation{
+ URL: url,
+ Title: title,
+ },
+ }
+ annotations = append(annotations, annotation)
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return annotations
+}
+
+// GenerateObject implements fantasy.LanguageModel.
+func (o languageModel) GenerateObject(ctx context.Context, call fantasy.ObjectCall) (*fantasy.ObjectResponse, error) {
+ switch o.objectMode {
+ case fantasy.ObjectModeText:
+ return object.GenerateWithText(ctx, o, call)
+ case fantasy.ObjectModeTool:
+ return object.GenerateWithTool(ctx, o, call)
+ default:
+ return o.generateObjectWithJSONMode(ctx, call)
+ }
+}
+
+// StreamObject implements fantasy.LanguageModel.
+func (o languageModel) StreamObject(ctx context.Context, call fantasy.ObjectCall) (fantasy.ObjectStreamResponse, error) {
+ switch o.objectMode {
+ case fantasy.ObjectModeTool:
+ return object.StreamWithTool(ctx, o, call)
+ case fantasy.ObjectModeText:
+ return object.StreamWithText(ctx, o, call)
+ default:
+ return o.streamObjectWithJSONMode(ctx, call)
+ }
+}
+
+func (o languageModel) generateObjectWithJSONMode(ctx context.Context, call fantasy.ObjectCall) (*fantasy.ObjectResponse, error) {
+ jsonSchemaMap := schema.ToMap(call.Schema)
+
+ addAdditionalPropertiesFalse(jsonSchemaMap)
+
+ schemaName := call.SchemaName
+ if schemaName == "" {
+ schemaName = "response"
+ }
+
+ fantasyCall := fantasy.Call{
+ Prompt: call.Prompt,
+ MaxOutputTokens: call.MaxOutputTokens,
+ Temperature: call.Temperature,
+ TopP: call.TopP,
+ PresencePenalty: call.PresencePenalty,
+ FrequencyPenalty: call.FrequencyPenalty,
+ ProviderOptions: call.ProviderOptions,
+ }
+
+ params, warnings, err := o.prepareParams(fantasyCall)
+ if err != nil {
+ return nil, err
+ }
+
+ params.ResponseFormat = openai.ChatCompletionNewParamsResponseFormatUnion{
+ OfJSONSchema: &shared.ResponseFormatJSONSchemaParam{
+ JSONSchema: shared.ResponseFormatJSONSchemaJSONSchemaParam{
+ Name: schemaName,
+ Description: param.NewOpt(call.SchemaDescription),
+ Schema: jsonSchemaMap,
+ Strict: param.NewOpt(true),
+ },
+ },
+ }
+
+ response, err := o.client.Chat.Completions.New(ctx, *params)
+ if err != nil {
+ return nil, toProviderErr(err)
+ }
+
+ if len(response.Choices) == 0 {
+ usage, _ := o.usageFunc(*response)
+ return nil, &fantasy.NoObjectGeneratedError{
+ RawText: "",
+ ParseError: fmt.Errorf("no choices in response"),
+ Usage: usage,
+ FinishReason: fantasy.FinishReasonUnknown,
+ }
+ }
+
+ choice := response.Choices[0]
+ jsonText := choice.Message.Content
+
+ var obj any
+ if call.RepairText != nil {
+ obj, err = schema.ParseAndValidateWithRepair(ctx, jsonText, call.Schema, call.RepairText)
+ } else {
+ obj, err = schema.ParseAndValidate(jsonText, call.Schema)
+ }
+
+ usage, _ := o.usageFunc(*response)
+ finishReason := o.mapFinishReasonFunc(choice.FinishReason)
+
+ if err != nil {
+ if nogErr, ok := err.(*fantasy.NoObjectGeneratedError); ok {
+ nogErr.Usage = usage
+ nogErr.FinishReason = finishReason
+ }
+ return nil, err
+ }
+
+ return &fantasy.ObjectResponse{
+ Object: obj,
+ RawText: jsonText,
+ Usage: usage,
+ FinishReason: finishReason,
+ Warnings: warnings,
+ }, nil
+}
+
+func (o languageModel) streamObjectWithJSONMode(ctx context.Context, call fantasy.ObjectCall) (fantasy.ObjectStreamResponse, error) {
+ jsonSchemaMap := schema.ToMap(call.Schema)
+
+ addAdditionalPropertiesFalse(jsonSchemaMap)
+
+ schemaName := call.SchemaName
+ if schemaName == "" {
+ schemaName = "response"
+ }
+
+ fantasyCall := fantasy.Call{
+ Prompt: call.Prompt,
+ MaxOutputTokens: call.MaxOutputTokens,
+ Temperature: call.Temperature,
+ TopP: call.TopP,
+ PresencePenalty: call.PresencePenalty,
+ FrequencyPenalty: call.FrequencyPenalty,
+ ProviderOptions: call.ProviderOptions,
+ }
+
+ params, warnings, err := o.prepareParams(fantasyCall)
+ if err != nil {
+ return nil, err
+ }
+
+ params.ResponseFormat = openai.ChatCompletionNewParamsResponseFormatUnion{
+ OfJSONSchema: &shared.ResponseFormatJSONSchemaParam{
+ JSONSchema: shared.ResponseFormatJSONSchemaJSONSchemaParam{
+ Name: schemaName,
+ Description: param.NewOpt(call.SchemaDescription),
+ Schema: jsonSchemaMap,
+ Strict: param.NewOpt(true),
+ },
+ },
+ }
+
+ params.StreamOptions = openai.ChatCompletionStreamOptionsParam{
+ IncludeUsage: openai.Bool(true),
+ }
+
+ stream := o.client.Chat.Completions.NewStreaming(ctx, *params)
+
+ return func(yield func(fantasy.ObjectStreamPart) bool) {
+ if len(warnings) > 0 {
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeObject,
+ Warnings: warnings,
+ }) {
+ return
+ }
+ }
+
+ var accumulated string
+ var lastParsedObject any
+ var usage fantasy.Usage
+ var finishReason fantasy.FinishReason
+ var providerMetadata fantasy.ProviderMetadata
+ var streamErr error
+
+ for stream.Next() {
+ chunk := stream.Current()
+
+ // Update usage
+ usage, providerMetadata = o.streamUsageFunc(chunk, make(map[string]any), providerMetadata)
+
+ if len(chunk.Choices) == 0 {
+ continue
+ }
+
+ choice := chunk.Choices[0]
+ if choice.FinishReason != "" {
+ finishReason = o.mapFinishReasonFunc(choice.FinishReason)
+ }
+
+ if choice.Delta.Content != "" {
+ accumulated += choice.Delta.Content
+
+ obj, state, parseErr := schema.ParsePartialJSON(accumulated)
+
+ if state == schema.ParseStateSuccessful || state == schema.ParseStateRepaired {
+ if err := schema.ValidateAgainstSchema(obj, call.Schema); err == nil {
+ if !reflect.DeepEqual(obj, lastParsedObject) {
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeObject,
+ Object: obj,
+ }) {
+ return
+ }
+ lastParsedObject = obj
+ }
+ }
+ }
+
+ if state == schema.ParseStateFailed && call.RepairText != nil {
+ repairedText, repairErr := call.RepairText(ctx, accumulated, parseErr)
+ if repairErr == nil {
+ obj2, state2, _ := schema.ParsePartialJSON(repairedText)
+ if (state2 == schema.ParseStateSuccessful || state2 == schema.ParseStateRepaired) &&
+ schema.ValidateAgainstSchema(obj2, call.Schema) == nil {
+ if !reflect.DeepEqual(obj2, lastParsedObject) {
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeObject,
+ Object: obj2,
+ }) {
+ return
+ }
+ lastParsedObject = obj2
+ }
+ }
+ }
+ }
+ }
+ }
+
+ err := stream.Err()
+ if err != nil && !errors.Is(err, io.EOF) {
+ streamErr = toProviderErr(err)
+ yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeError,
+ Error: streamErr,
+ })
+ return
+ }
+
+ if lastParsedObject != nil {
+ yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeFinish,
+ Usage: usage,
+ FinishReason: finishReason,
+ ProviderMetadata: providerMetadata,
+ })
+ } else {
+ yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeError,
+ Error: &fantasy.NoObjectGeneratedError{
+ RawText: accumulated,
+ ParseError: fmt.Errorf("no valid object generated in stream"),
+ Usage: usage,
+ FinishReason: finishReason,
+ },
+ })
+ }
+ }, nil
+}
+
+// addAdditionalPropertiesFalse recursively adds "additionalProperties": false to all object schemas.
+// This is required by OpenAI's strict mode for structured outputs.
+func addAdditionalPropertiesFalse(schema map[string]any) {
+ if schema["type"] == "object" {
+ if _, hasAdditional := schema["additionalProperties"]; !hasAdditional {
+ schema["additionalProperties"] = false
+ }
+
+ // Recursively process nested properties
+ if properties, ok := schema["properties"].(map[string]any); ok {
+ for _, propValue := range properties {
+ if propSchema, ok := propValue.(map[string]any); ok {
+ addAdditionalPropertiesFalse(propSchema)
+ }
+ }
+ }
+ }
+
+ // Handle array items
+ if items, ok := schema["items"].(map[string]any); ok {
+ addAdditionalPropertiesFalse(items)
+ }
+}
diff --git a/internal/fantasy/providers/openai/language_model_hooks.go b/internal/fantasy/providers/openai/language_model_hooks.go
new file mode 100644
index 000000000..d58c1794f
--- /dev/null
+++ b/internal/fantasy/providers/openai/language_model_hooks.go
@@ -0,0 +1,578 @@
+package openai
+
+import (
+ "encoding/base64"
+ "fmt"
+ "strings"
+
+ "charm.land/fantasy"
+ "github.com/openai/openai-go/v2"
+ "github.com/openai/openai-go/v2/packages/param"
+ "github.com/openai/openai-go/v2/shared"
+)
+
+// LanguageModelPrepareCallFunc is a function that prepares the call for the language model.
+type LanguageModelPrepareCallFunc = func(model fantasy.LanguageModel, params *openai.ChatCompletionNewParams, call fantasy.Call) ([]fantasy.CallWarning, error)
+
+// LanguageModelMapFinishReasonFunc is a function that maps the finish reason for the language model.
+type LanguageModelMapFinishReasonFunc = func(finishReason string) fantasy.FinishReason
+
+// LanguageModelUsageFunc is a function that calculates usage for the language model.
+type LanguageModelUsageFunc = func(choice openai.ChatCompletion) (fantasy.Usage, fantasy.ProviderOptionsData)
+
+// LanguageModelExtraContentFunc is a function that adds extra content for the language model.
+type LanguageModelExtraContentFunc = func(choice openai.ChatCompletionChoice) []fantasy.Content
+
+// LanguageModelStreamExtraFunc is a function that handles stream extra functionality for the language model.
+type LanguageModelStreamExtraFunc = func(chunk openai.ChatCompletionChunk, yield func(fantasy.StreamPart) bool, ctx map[string]any) (map[string]any, bool)
+
+// LanguageModelStreamUsageFunc is a function that calculates stream usage for the language model.
+type LanguageModelStreamUsageFunc = func(chunk openai.ChatCompletionChunk, ctx map[string]any, metadata fantasy.ProviderMetadata) (fantasy.Usage, fantasy.ProviderMetadata)
+
+// LanguageModelStreamProviderMetadataFunc is a function that handles stream provider metadata for the language model.
+type LanguageModelStreamProviderMetadataFunc = func(choice openai.ChatCompletionChoice, metadata fantasy.ProviderMetadata) fantasy.ProviderMetadata
+
+// LanguageModelToPromptFunc is a function that handles converting fantasy prompts to openai sdk messages.
+type LanguageModelToPromptFunc = func(prompt fantasy.Prompt, provider, model string) ([]openai.ChatCompletionMessageParamUnion, []fantasy.CallWarning)
+
+// DefaultPrepareCallFunc is the default implementation for preparing a call to the language model.
+func DefaultPrepareCallFunc(model fantasy.LanguageModel, params *openai.ChatCompletionNewParams, call fantasy.Call) ([]fantasy.CallWarning, error) {
+ if call.ProviderOptions == nil {
+ return nil, nil
+ }
+ var warnings []fantasy.CallWarning
+ providerOptions := &ProviderOptions{}
+ if v, ok := call.ProviderOptions[Name]; ok {
+ providerOptions, ok = v.(*ProviderOptions)
+ if !ok {
+ return nil, &fantasy.Error{Title: "invalid argument", Message: "openai provider options should be *openai.ProviderOptions"}
+ }
+ }
+
+ if providerOptions.LogitBias != nil {
+ params.LogitBias = providerOptions.LogitBias
+ }
+ if providerOptions.LogProbs != nil && providerOptions.TopLogProbs != nil {
+ providerOptions.LogProbs = nil
+ }
+ if providerOptions.LogProbs != nil {
+ params.Logprobs = param.NewOpt(*providerOptions.LogProbs)
+ }
+ if providerOptions.TopLogProbs != nil {
+ params.TopLogprobs = param.NewOpt(*providerOptions.TopLogProbs)
+ }
+ if providerOptions.User != nil {
+ params.User = param.NewOpt(*providerOptions.User)
+ }
+ if providerOptions.ParallelToolCalls != nil {
+ params.ParallelToolCalls = param.NewOpt(*providerOptions.ParallelToolCalls)
+ }
+ if providerOptions.MaxCompletionTokens != nil {
+ params.MaxCompletionTokens = param.NewOpt(*providerOptions.MaxCompletionTokens)
+ }
+
+ if providerOptions.TextVerbosity != nil {
+ params.Verbosity = openai.ChatCompletionNewParamsVerbosity(*providerOptions.TextVerbosity)
+ }
+ if providerOptions.Prediction != nil {
+ // Convert map[string]any to ChatCompletionPredictionContentParam
+ if content, ok := providerOptions.Prediction["content"]; ok {
+ if contentStr, ok := content.(string); ok {
+ params.Prediction = openai.ChatCompletionPredictionContentParam{
+ Content: openai.ChatCompletionPredictionContentContentUnionParam{
+ OfString: param.NewOpt(contentStr),
+ },
+ }
+ }
+ }
+ }
+ if providerOptions.Store != nil {
+ params.Store = param.NewOpt(*providerOptions.Store)
+ }
+ if providerOptions.Metadata != nil {
+ // Convert map[string]any to map[string]string
+ metadata := make(map[string]string)
+ for k, v := range providerOptions.Metadata {
+ if str, ok := v.(string); ok {
+ metadata[k] = str
+ }
+ }
+ params.Metadata = metadata
+ }
+ if providerOptions.PromptCacheKey != nil {
+ params.PromptCacheKey = param.NewOpt(*providerOptions.PromptCacheKey)
+ }
+ if providerOptions.SafetyIdentifier != nil {
+ params.SafetyIdentifier = param.NewOpt(*providerOptions.SafetyIdentifier)
+ }
+ if providerOptions.ServiceTier != nil {
+ params.ServiceTier = openai.ChatCompletionNewParamsServiceTier(*providerOptions.ServiceTier)
+ }
+
+ if providerOptions.ReasoningEffort != nil {
+ switch *providerOptions.ReasoningEffort {
+ case ReasoningEffortMinimal:
+ params.ReasoningEffort = shared.ReasoningEffortMinimal
+ case ReasoningEffortLow:
+ params.ReasoningEffort = shared.ReasoningEffortLow
+ case ReasoningEffortMedium:
+ params.ReasoningEffort = shared.ReasoningEffortMedium
+ case ReasoningEffortHigh:
+ params.ReasoningEffort = shared.ReasoningEffortHigh
+ default:
+ return nil, fmt.Errorf("reasoning model `%s` not supported", *providerOptions.ReasoningEffort)
+ }
+ }
+
+ if isReasoningModel(model.Model()) {
+ if providerOptions.LogitBias != nil {
+ params.LogitBias = nil
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "LogitBias",
+ Message: "LogitBias is not supported for reasoning models",
+ })
+ }
+ if providerOptions.LogProbs != nil {
+ params.Logprobs = param.Opt[bool]{}
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "Logprobs",
+ Message: "Logprobs is not supported for reasoning models",
+ })
+ }
+ if providerOptions.TopLogProbs != nil {
+ params.TopLogprobs = param.Opt[int64]{}
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "TopLogprobs",
+ Message: "TopLogprobs is not supported for reasoning models",
+ })
+ }
+ }
+
+ // Handle service tier validation
+ if providerOptions.ServiceTier != nil {
+ serviceTier := *providerOptions.ServiceTier
+ if serviceTier == "flex" && !supportsFlexProcessing(model.Model()) {
+ params.ServiceTier = ""
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "ServiceTier",
+ Details: "flex processing is only available for o3, o4-mini, and gpt-5 models",
+ })
+ } else if serviceTier == "priority" && !supportsPriorityProcessing(model.Model()) {
+ params.ServiceTier = ""
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "ServiceTier",
+ Details: "priority processing is only available for supported models (gpt-4, gpt-5, gpt-5-mini, o3, o4-mini) and requires Enterprise access. gpt-5-nano is not supported",
+ })
+ }
+ }
+ return warnings, nil
+}
+
+// DefaultMapFinishReasonFunc is the default implementation for mapping finish reasons.
+func DefaultMapFinishReasonFunc(finishReason string) fantasy.FinishReason {
+ switch finishReason {
+ case "stop":
+ return fantasy.FinishReasonStop
+ case "length":
+ return fantasy.FinishReasonLength
+ case "content_filter":
+ return fantasy.FinishReasonContentFilter
+ case "function_call", "tool_calls":
+ return fantasy.FinishReasonToolCalls
+ default:
+ return fantasy.FinishReasonUnknown
+ }
+}
+
+// DefaultUsageFunc is the default implementation for calculating usage.
+func DefaultUsageFunc(response openai.ChatCompletion) (fantasy.Usage, fantasy.ProviderOptionsData) {
+ completionTokenDetails := response.Usage.CompletionTokensDetails
+ promptTokenDetails := response.Usage.PromptTokensDetails
+
+ // Build provider metadata
+ providerMetadata := &ProviderMetadata{}
+
+ // Add logprobs if available
+ if len(response.Choices) > 0 && len(response.Choices[0].Logprobs.Content) > 0 {
+ providerMetadata.Logprobs = response.Choices[0].Logprobs.Content
+ }
+
+ // Add prediction tokens if available
+ if completionTokenDetails.AcceptedPredictionTokens > 0 || completionTokenDetails.RejectedPredictionTokens > 0 {
+ if completionTokenDetails.AcceptedPredictionTokens > 0 {
+ providerMetadata.AcceptedPredictionTokens = completionTokenDetails.AcceptedPredictionTokens
+ }
+ if completionTokenDetails.RejectedPredictionTokens > 0 {
+ providerMetadata.RejectedPredictionTokens = completionTokenDetails.RejectedPredictionTokens
+ }
+ }
+ return fantasy.Usage{
+ InputTokens: response.Usage.PromptTokens,
+ OutputTokens: response.Usage.CompletionTokens,
+ TotalTokens: response.Usage.TotalTokens,
+ ReasoningTokens: completionTokenDetails.ReasoningTokens,
+ CacheReadTokens: promptTokenDetails.CachedTokens,
+ }, providerMetadata
+}
+
+// DefaultStreamUsageFunc is the default implementation for calculating stream usage.
+func DefaultStreamUsageFunc(chunk openai.ChatCompletionChunk, _ map[string]any, metadata fantasy.ProviderMetadata) (fantasy.Usage, fantasy.ProviderMetadata) {
+ if chunk.Usage.TotalTokens == 0 {
+ return fantasy.Usage{}, nil
+ }
+ streamProviderMetadata := &ProviderMetadata{}
+ if metadata != nil {
+ if providerMetadata, ok := metadata[Name]; ok {
+ converted, ok := providerMetadata.(*ProviderMetadata)
+ if ok {
+ streamProviderMetadata = converted
+ }
+ }
+ }
+ // we do this here because the acc does not add prompt details
+ completionTokenDetails := chunk.Usage.CompletionTokensDetails
+ promptTokenDetails := chunk.Usage.PromptTokensDetails
+ usage := fantasy.Usage{
+ InputTokens: chunk.Usage.PromptTokens,
+ OutputTokens: chunk.Usage.CompletionTokens,
+ TotalTokens: chunk.Usage.TotalTokens,
+ ReasoningTokens: completionTokenDetails.ReasoningTokens,
+ CacheReadTokens: promptTokenDetails.CachedTokens,
+ }
+
+ // Add prediction tokens if available
+ if completionTokenDetails.AcceptedPredictionTokens > 0 || completionTokenDetails.RejectedPredictionTokens > 0 {
+ if completionTokenDetails.AcceptedPredictionTokens > 0 {
+ streamProviderMetadata.AcceptedPredictionTokens = completionTokenDetails.AcceptedPredictionTokens
+ }
+ if completionTokenDetails.RejectedPredictionTokens > 0 {
+ streamProviderMetadata.RejectedPredictionTokens = completionTokenDetails.RejectedPredictionTokens
+ }
+ }
+
+ return usage, fantasy.ProviderMetadata{
+ Name: streamProviderMetadata,
+ }
+}
+
+// DefaultStreamProviderMetadataFunc is the default implementation for handling stream provider metadata.
+func DefaultStreamProviderMetadataFunc(choice openai.ChatCompletionChoice, metadata fantasy.ProviderMetadata) fantasy.ProviderMetadata {
+ if metadata == nil {
+ metadata = fantasy.ProviderMetadata{}
+ }
+ streamProviderMetadata, ok := metadata[Name]
+ if !ok {
+ streamProviderMetadata = &ProviderMetadata{}
+ }
+ if converted, ok := streamProviderMetadata.(*ProviderMetadata); ok {
+ converted.Logprobs = choice.Logprobs.Content
+ metadata[Name] = converted
+ }
+ return metadata
+}
+
+// DefaultToPrompt converts a fantasy prompt to OpenAI format with default handling.
+func DefaultToPrompt(prompt fantasy.Prompt, _, _ string) ([]openai.ChatCompletionMessageParamUnion, []fantasy.CallWarning) {
+ var messages []openai.ChatCompletionMessageParamUnion
+ var warnings []fantasy.CallWarning
+ for _, msg := range prompt {
+ switch msg.Role {
+ case fantasy.MessageRoleSystem:
+ var systemPromptParts []string
+ for _, c := range msg.Content {
+ if c.GetType() != fantasy.ContentTypeText {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "system prompt can only have text content",
+ })
+ continue
+ }
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "system prompt text part does not have the right type",
+ })
+ continue
+ }
+ text := textPart.Text
+ if strings.TrimSpace(text) != "" {
+ systemPromptParts = append(systemPromptParts, textPart.Text)
+ }
+ }
+ if len(systemPromptParts) == 0 {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "system prompt has no text parts",
+ })
+ continue
+ }
+ messages = append(messages, openai.SystemMessage(strings.Join(systemPromptParts, "\n")))
+ case fantasy.MessageRoleUser:
+ // simple user message just text content
+ if len(msg.Content) == 1 && msg.Content[0].GetType() == fantasy.ContentTypeText {
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](msg.Content[0])
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "user message text part does not have the right type",
+ })
+ continue
+ }
+ messages = append(messages, openai.UserMessage(textPart.Text))
+ continue
+ }
+ // text content and attachments
+ // for now we only support image content later we need to check
+ // TODO: add the supported media types to the language model so we
+ // can use that to validate the data here.
+ var content []openai.ChatCompletionContentPartUnionParam
+ for _, c := range msg.Content {
+ switch c.GetType() {
+ case fantasy.ContentTypeText:
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "user message text part does not have the right type",
+ })
+ continue
+ }
+ content = append(content, openai.ChatCompletionContentPartUnionParam{
+ OfText: &openai.ChatCompletionContentPartTextParam{
+ Text: textPart.Text,
+ },
+ })
+ case fantasy.ContentTypeFile:
+ filePart, ok := fantasy.AsContentType[fantasy.FilePart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "user message file part does not have the right type",
+ })
+ continue
+ }
+
+ switch {
+ case strings.HasPrefix(filePart.MediaType, "image/"):
+ // Handle image files
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ data := "data:" + filePart.MediaType + ";base64," + base64Encoded
+ imageURL := openai.ChatCompletionContentPartImageImageURLParam{URL: data}
+
+ // Check for provider-specific options like image detail
+ if providerOptions, ok := filePart.ProviderOptions[Name]; ok {
+ if detail, ok := providerOptions.(*ProviderFileOptions); ok {
+ imageURL.Detail = detail.ImageDetail
+ }
+ }
+
+ imageBlock := openai.ChatCompletionContentPartImageParam{ImageURL: imageURL}
+ content = append(content, openai.ChatCompletionContentPartUnionParam{OfImageURL: &imageBlock})
+
+ case filePart.MediaType == "audio/wav":
+ // Handle WAV audio files
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ audioBlock := openai.ChatCompletionContentPartInputAudioParam{
+ InputAudio: openai.ChatCompletionContentPartInputAudioInputAudioParam{
+ Data: base64Encoded,
+ Format: "wav",
+ },
+ }
+ content = append(content, openai.ChatCompletionContentPartUnionParam{OfInputAudio: &audioBlock})
+
+ case filePart.MediaType == "audio/mpeg" || filePart.MediaType == "audio/mp3":
+ // Handle MP3 audio files
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ audioBlock := openai.ChatCompletionContentPartInputAudioParam{
+ InputAudio: openai.ChatCompletionContentPartInputAudioInputAudioParam{
+ Data: base64Encoded,
+ Format: "mp3",
+ },
+ }
+ content = append(content, openai.ChatCompletionContentPartUnionParam{OfInputAudio: &audioBlock})
+
+ case filePart.MediaType == "application/pdf":
+ // Handle PDF files
+ dataStr := string(filePart.Data)
+
+ // Check if data looks like a file ID (starts with "file-")
+ if strings.HasPrefix(dataStr, "file-") {
+ fileBlock := openai.ChatCompletionContentPartFileParam{
+ File: openai.ChatCompletionContentPartFileFileParam{
+ FileID: param.NewOpt(dataStr),
+ },
+ }
+ content = append(content, openai.ChatCompletionContentPartUnionParam{OfFile: &fileBlock})
+ } else {
+ // Handle as base64 data
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ data := "data:application/pdf;base64," + base64Encoded
+
+ filename := filePart.Filename
+ if filename == "" {
+ // Generate default filename based on content index
+ filename = fmt.Sprintf("part-%d.pdf", len(content))
+ }
+
+ fileBlock := openai.ChatCompletionContentPartFileParam{
+ File: openai.ChatCompletionContentPartFileFileParam{
+ Filename: param.NewOpt(filename),
+ FileData: param.NewOpt(data),
+ },
+ }
+ content = append(content, openai.ChatCompletionContentPartUnionParam{OfFile: &fileBlock})
+ }
+
+ default:
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: fmt.Sprintf("file part media type %s not supported", filePart.MediaType),
+ })
+ }
+ }
+ }
+ if !hasVisibleUserContent(content) {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "dropping empty user message (contains neither user-facing content nor tool results)",
+ })
+ continue
+ }
+ messages = append(messages, openai.UserMessage(content))
+ case fantasy.MessageRoleAssistant:
+ // simple assistant message just text content
+ if len(msg.Content) == 1 && msg.Content[0].GetType() == fantasy.ContentTypeText {
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](msg.Content[0])
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message text part does not have the right type",
+ })
+ continue
+ }
+ messages = append(messages, openai.AssistantMessage(textPart.Text))
+ continue
+ }
+ assistantMsg := openai.ChatCompletionAssistantMessageParam{
+ Role: "assistant",
+ }
+ for _, c := range msg.Content {
+ switch c.GetType() {
+ case fantasy.ContentTypeText:
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message text part does not have the right type",
+ })
+ continue
+ }
+ assistantMsg.Content = openai.ChatCompletionAssistantMessageParamContentUnion{
+ OfString: param.NewOpt(textPart.Text),
+ }
+ case fantasy.ContentTypeToolCall:
+ toolCallPart, ok := fantasy.AsContentType[fantasy.ToolCallPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message tool part does not have the right type",
+ })
+ continue
+ }
+ assistantMsg.ToolCalls = append(assistantMsg.ToolCalls,
+ openai.ChatCompletionMessageToolCallUnionParam{
+ OfFunction: &openai.ChatCompletionMessageFunctionToolCallParam{
+ ID: toolCallPart.ToolCallID,
+ Type: "function",
+ Function: openai.ChatCompletionMessageFunctionToolCallFunctionParam{
+ Name: toolCallPart.ToolName,
+ Arguments: toolCallPart.Input,
+ },
+ },
+ })
+ }
+ }
+ if !hasVisibleAssistantContent(&assistantMsg) {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "dropping empty assistant message (contains neither user-facing content nor tool calls)",
+ })
+ continue
+ }
+ messages = append(messages, openai.ChatCompletionMessageParamUnion{
+ OfAssistant: &assistantMsg,
+ })
+ case fantasy.MessageRoleTool:
+ for _, c := range msg.Content {
+ if c.GetType() != fantasy.ContentTypeToolResult {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool message can only have tool result content",
+ })
+ continue
+ }
+
+ toolResultPart, ok := fantasy.AsContentType[fantasy.ToolResultPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool message result part does not have the right type",
+ })
+ continue
+ }
+
+ switch toolResultPart.Output.GetType() {
+ case fantasy.ToolResultContentTypeText:
+ output, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentText](toolResultPart.Output)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool result output does not have the right type",
+ })
+ continue
+ }
+ messages = append(messages, openai.ToolMessage(output.Text, toolResultPart.ToolCallID))
+ case fantasy.ToolResultContentTypeError:
+ // TODO: check if better handling is needed
+ output, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentError](toolResultPart.Output)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool result output does not have the right type",
+ })
+ continue
+ }
+ messages = append(messages, openai.ToolMessage(output.Error.Error(), toolResultPart.ToolCallID))
+ }
+ }
+ }
+ }
+ return messages, warnings
+}
+
+func hasVisibleUserContent(content []openai.ChatCompletionContentPartUnionParam) bool {
+ for _, part := range content {
+ if part.OfText != nil || part.OfImageURL != nil || part.OfInputAudio != nil || part.OfFile != nil {
+ return true
+ }
+ }
+ return false
+}
+
+func hasVisibleAssistantContent(msg *openai.ChatCompletionAssistantMessageParam) bool {
+ // Check if there's text content
+ if !param.IsOmitted(msg.Content.OfString) || len(msg.Content.OfArrayOfContentParts) > 0 {
+ return true
+ }
+ // Check if there are tool calls
+ if len(msg.ToolCalls) > 0 {
+ return true
+ }
+ return false
+}
diff --git a/internal/fantasy/providers/openai/openai.go b/internal/fantasy/providers/openai/openai.go
new file mode 100644
index 000000000..7ca74b9c7
--- /dev/null
+++ b/internal/fantasy/providers/openai/openai.go
@@ -0,0 +1,191 @@
+// Package openai provides an implementation of the fantasy AI SDK for OpenAI's language models.
+package openai
+
+import (
+ "cmp"
+ "context"
+ "maps"
+
+ "charm.land/fantasy"
+ "github.com/openai/openai-go/v2"
+ "github.com/openai/openai-go/v2/option"
+)
+
+const (
+ // Name is the name of the OpenAI provider.
+ Name = "openai"
+ // DefaultURL is the default URL for the OpenAI API.
+ DefaultURL = "https://api.openai.com/v1"
+)
+
+type provider struct {
+ options options
+}
+
+type options struct {
+ baseURL string
+ apiKey string
+ organization string
+ project string
+ name string
+ useResponsesAPI bool
+ headers map[string]string
+ client option.HTTPClient
+ sdkOptions []option.RequestOption
+ objectMode fantasy.ObjectMode
+ languageModelOptions []LanguageModelOption
+}
+
+// Option defines a function that configures OpenAI provider options.
+type Option = func(*options)
+
+// New creates a new OpenAI provider with the given options.
+func New(opts ...Option) (fantasy.Provider, error) {
+ providerOptions := options{
+ headers: map[string]string{},
+ languageModelOptions: make([]LanguageModelOption, 0),
+ }
+ for _, o := range opts {
+ o(&providerOptions)
+ }
+
+ providerOptions.baseURL = cmp.Or(providerOptions.baseURL, DefaultURL)
+ providerOptions.name = cmp.Or(providerOptions.name, Name)
+
+ if providerOptions.organization != "" {
+ providerOptions.headers["OpenAi-Organization"] = providerOptions.organization
+ }
+ if providerOptions.project != "" {
+ providerOptions.headers["OpenAi-Project"] = providerOptions.project
+ }
+
+ return &provider{options: providerOptions}, nil
+}
+
+// WithBaseURL sets the base URL for the OpenAI provider.
+func WithBaseURL(baseURL string) Option {
+ return func(o *options) {
+ o.baseURL = baseURL
+ }
+}
+
+// WithAPIKey sets the API key for the OpenAI provider.
+func WithAPIKey(apiKey string) Option {
+ return func(o *options) {
+ o.apiKey = apiKey
+ }
+}
+
+// WithOrganization sets the organization for the OpenAI provider.
+func WithOrganization(organization string) Option {
+ return func(o *options) {
+ o.organization = organization
+ }
+}
+
+// WithProject sets the project for the OpenAI provider.
+func WithProject(project string) Option {
+ return func(o *options) {
+ o.project = project
+ }
+}
+
+// WithName sets the name for the OpenAI provider.
+func WithName(name string) Option {
+ return func(o *options) {
+ o.name = name
+ }
+}
+
+// WithHeaders sets the headers for the OpenAI provider.
+func WithHeaders(headers map[string]string) Option {
+ return func(o *options) {
+ maps.Copy(o.headers, headers)
+ }
+}
+
+// WithHTTPClient sets the HTTP client for the OpenAI provider.
+func WithHTTPClient(client option.HTTPClient) Option {
+ return func(o *options) {
+ o.client = client
+ }
+}
+
+// WithSDKOptions sets the SDK options for the OpenAI provider.
+func WithSDKOptions(opts ...option.RequestOption) Option {
+ return func(o *options) {
+ o.sdkOptions = append(o.sdkOptions, opts...)
+ }
+}
+
+// WithLanguageModelOptions sets the language model options for the OpenAI provider.
+func WithLanguageModelOptions(opts ...LanguageModelOption) Option {
+ return func(o *options) {
+ o.languageModelOptions = append(o.languageModelOptions, opts...)
+ }
+}
+
+// WithUseResponsesAPI configures the provider to use the responses API for models that support it.
+func WithUseResponsesAPI() Option {
+ return func(o *options) {
+ o.useResponsesAPI = true
+ }
+}
+
+// WithObjectMode sets the object generation mode.
+func WithObjectMode(om fantasy.ObjectMode) Option {
+ return func(o *options) {
+ // not supported
+ if om == fantasy.ObjectModeJSON {
+ om = fantasy.ObjectModeAuto
+ }
+ o.objectMode = om
+ }
+}
+
+// LanguageModel implements fantasy.Provider.
+func (o *provider) LanguageModel(_ context.Context, modelID string) (fantasy.LanguageModel, error) {
+ openaiClientOptions := make([]option.RequestOption, 0, 5+len(o.options.headers)+len(o.options.sdkOptions))
+ openaiClientOptions = append(openaiClientOptions, option.WithMaxRetries(0))
+
+ if o.options.apiKey != "" {
+ openaiClientOptions = append(openaiClientOptions, option.WithAPIKey(o.options.apiKey))
+ }
+ if o.options.baseURL != "" {
+ openaiClientOptions = append(openaiClientOptions, option.WithBaseURL(o.options.baseURL))
+ }
+
+ for key, value := range o.options.headers {
+ openaiClientOptions = append(openaiClientOptions, option.WithHeader(key, value))
+ }
+
+ if o.options.client != nil {
+ openaiClientOptions = append(openaiClientOptions, option.WithHTTPClient(o.options.client))
+ }
+
+ openaiClientOptions = append(openaiClientOptions, o.options.sdkOptions...)
+
+ client := openai.NewClient(openaiClientOptions...)
+
+ if o.options.useResponsesAPI && IsResponsesModel(modelID) {
+ // Not supported for responses API
+ objectMode := o.options.objectMode
+ if objectMode == fantasy.ObjectModeJSON {
+ objectMode = fantasy.ObjectModeAuto
+ }
+ return newResponsesLanguageModel(modelID, o.options.name, client, objectMode), nil
+ }
+
+ o.options.languageModelOptions = append(o.options.languageModelOptions, WithLanguageModelObjectMode(o.options.objectMode))
+
+ return newLanguageModel(
+ modelID,
+ o.options.name,
+ client,
+ o.options.languageModelOptions...,
+ ), nil
+}
+
+func (o *provider) Name() string {
+ return Name
+}
diff --git a/internal/fantasy/providers/openai/openai_test.go b/internal/fantasy/providers/openai/openai_test.go
new file mode 100644
index 000000000..adc1cf2e8
--- /dev/null
+++ b/internal/fantasy/providers/openai/openai_test.go
@@ -0,0 +1,3249 @@
+package openai
+
+import (
+ "context"
+ "encoding/base64"
+ "encoding/json"
+ "errors"
+ "net/http"
+ "net/http/httptest"
+ "strings"
+ "testing"
+
+ "charm.land/fantasy"
+ "github.com/openai/openai-go/v2/packages/param"
+ "github.com/stretchr/testify/require"
+)
+
+func TestToOpenAiPrompt_SystemMessages(t *testing.T) {
+ t.Parallel()
+
+ t.Run("should forward system messages", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleSystem,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "You are a helpful assistant."},
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 1)
+
+ systemMsg := messages[0].OfSystem
+ require.NotNil(t, systemMsg)
+ require.Equal(t, "You are a helpful assistant.", systemMsg.Content.OfString.Value)
+ })
+
+ t.Run("should handle empty system messages", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleSystem,
+ Content: []fantasy.MessagePart{},
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Len(t, warnings, 1)
+ require.Contains(t, warnings[0].Message, "system prompt has no text parts")
+ require.Empty(t, messages)
+ })
+
+ t.Run("should join multiple system text parts", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleSystem,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "You are a helpful assistant."},
+ fantasy.TextPart{Text: "Be concise."},
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 1)
+
+ systemMsg := messages[0].OfSystem
+ require.NotNil(t, systemMsg)
+ require.Equal(t, "You are a helpful assistant.\nBe concise.", systemMsg.Content.OfString.Value)
+ })
+}
+
+func TestToOpenAiPrompt_UserMessages(t *testing.T) {
+ t.Parallel()
+
+ t.Run("should convert messages with only a text part to a string content", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 1)
+
+ userMsg := messages[0].OfUser
+ require.NotNil(t, userMsg)
+ require.Equal(t, "Hello", userMsg.Content.OfString.Value)
+ })
+
+ t.Run("should convert messages with image parts", func(t *testing.T) {
+ t.Parallel()
+
+ imageData := []byte{0, 1, 2, 3}
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ fantasy.FilePart{
+ MediaType: "image/png",
+ Data: imageData,
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 1)
+
+ userMsg := messages[0].OfUser
+ require.NotNil(t, userMsg)
+
+ content := userMsg.Content.OfArrayOfContentParts
+ require.Len(t, content, 2)
+
+ // Check text part
+ textPart := content[0].OfText
+ require.NotNil(t, textPart)
+ require.Equal(t, "Hello", textPart.Text)
+
+ // Check image part
+ imagePart := content[1].OfImageURL
+ require.NotNil(t, imagePart)
+ expectedURL := "data:image/png;base64," + base64.StdEncoding.EncodeToString(imageData)
+ require.Equal(t, expectedURL, imagePart.ImageURL.URL)
+ })
+
+ t.Run("should add image detail when specified through provider options", func(t *testing.T) {
+ t.Parallel()
+
+ imageData := []byte{0, 1, 2, 3}
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ MediaType: "image/png",
+ Data: imageData,
+ ProviderOptions: NewProviderFileOptions(&ProviderFileOptions{
+ ImageDetail: "low",
+ }),
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 1)
+
+ userMsg := messages[0].OfUser
+ require.NotNil(t, userMsg)
+
+ content := userMsg.Content.OfArrayOfContentParts
+ require.Len(t, content, 1)
+
+ imagePart := content[0].OfImageURL
+ require.NotNil(t, imagePart)
+ require.Equal(t, "low", imagePart.ImageURL.Detail)
+ })
+}
+
+func TestToOpenAiPrompt_FileParts(t *testing.T) {
+ t.Parallel()
+
+ t.Run("should throw for unsupported mime types", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ MediaType: "application/something",
+ Data: []byte("test"),
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Len(t, warnings, 2) // unsupported type + empty message
+ require.Contains(t, warnings[0].Message, "file part media type application/something not supported")
+ require.Contains(t, warnings[1].Message, "dropping empty user message")
+ require.Empty(t, messages) // Message is now dropped because it's empty
+ })
+
+ t.Run("should add audio content for audio/wav file parts", func(t *testing.T) {
+ t.Parallel()
+
+ audioData := []byte{0, 1, 2, 3}
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ MediaType: "audio/wav",
+ Data: audioData,
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 1)
+
+ userMsg := messages[0].OfUser
+ require.NotNil(t, userMsg)
+
+ content := userMsg.Content.OfArrayOfContentParts
+ require.Len(t, content, 1)
+
+ audioPart := content[0].OfInputAudio
+ require.NotNil(t, audioPart)
+ require.Equal(t, base64.StdEncoding.EncodeToString(audioData), audioPart.InputAudio.Data)
+ require.Equal(t, "wav", audioPart.InputAudio.Format)
+ })
+
+ t.Run("should add audio content for audio/mpeg file parts", func(t *testing.T) {
+ t.Parallel()
+
+ audioData := []byte{0, 1, 2, 3}
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ MediaType: "audio/mpeg",
+ Data: audioData,
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 1)
+
+ userMsg := messages[0].OfUser
+ content := userMsg.Content.OfArrayOfContentParts
+ audioPart := content[0].OfInputAudio
+ require.NotNil(t, audioPart)
+ require.Equal(t, "mp3", audioPart.InputAudio.Format)
+ })
+
+ t.Run("should add audio content for audio/mp3 file parts", func(t *testing.T) {
+ t.Parallel()
+
+ audioData := []byte{0, 1, 2, 3}
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ MediaType: "audio/mp3",
+ Data: audioData,
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 1)
+
+ userMsg := messages[0].OfUser
+ content := userMsg.Content.OfArrayOfContentParts
+ audioPart := content[0].OfInputAudio
+ require.NotNil(t, audioPart)
+ require.Equal(t, "mp3", audioPart.InputAudio.Format)
+ })
+
+ t.Run("should convert messages with PDF file parts", func(t *testing.T) {
+ t.Parallel()
+
+ pdfData := []byte{1, 2, 3, 4, 5}
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ MediaType: "application/pdf",
+ Data: pdfData,
+ Filename: "document.pdf",
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 1)
+
+ userMsg := messages[0].OfUser
+ content := userMsg.Content.OfArrayOfContentParts
+ require.Len(t, content, 1)
+
+ filePart := content[0].OfFile
+ require.NotNil(t, filePart)
+ require.Equal(t, "document.pdf", filePart.File.Filename.Value)
+
+ expectedData := "data:application/pdf;base64," + base64.StdEncoding.EncodeToString(pdfData)
+ require.Equal(t, expectedData, filePart.File.FileData.Value)
+ })
+
+ t.Run("should convert messages with binary PDF file parts", func(t *testing.T) {
+ t.Parallel()
+
+ pdfData := []byte{1, 2, 3, 4, 5}
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ MediaType: "application/pdf",
+ Data: pdfData,
+ Filename: "document.pdf",
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 1)
+
+ userMsg := messages[0].OfUser
+ content := userMsg.Content.OfArrayOfContentParts
+ filePart := content[0].OfFile
+ require.NotNil(t, filePart)
+
+ expectedData := "data:application/pdf;base64," + base64.StdEncoding.EncodeToString(pdfData)
+ require.Equal(t, expectedData, filePart.File.FileData.Value)
+ })
+
+ t.Run("should convert messages with PDF file parts using file_id", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ MediaType: "application/pdf",
+ Data: []byte("file-pdf-12345"),
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 1)
+
+ userMsg := messages[0].OfUser
+ content := userMsg.Content.OfArrayOfContentParts
+ filePart := content[0].OfFile
+ require.NotNil(t, filePart)
+ require.Equal(t, "file-pdf-12345", filePart.File.FileID.Value)
+ require.True(t, param.IsOmitted(filePart.File.FileData))
+ require.True(t, param.IsOmitted(filePart.File.Filename))
+ })
+
+ t.Run("should use default filename for PDF file parts when not provided", func(t *testing.T) {
+ t.Parallel()
+
+ pdfData := []byte{1, 2, 3, 4, 5}
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ MediaType: "application/pdf",
+ Data: pdfData,
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 1)
+
+ userMsg := messages[0].OfUser
+ content := userMsg.Content.OfArrayOfContentParts
+ filePart := content[0].OfFile
+ require.NotNil(t, filePart)
+ require.Equal(t, "part-0.pdf", filePart.File.Filename.Value)
+ })
+}
+
+func TestToOpenAiPrompt_ToolCalls(t *testing.T) {
+ t.Parallel()
+
+ t.Run("should stringify arguments to tool calls", func(t *testing.T) {
+ t.Parallel()
+
+ inputArgs := map[string]any{"foo": "bar123"}
+ inputJSON, _ := json.Marshal(inputArgs)
+
+ outputResult := map[string]any{"oof": "321rab"}
+ outputJSON, _ := json.Marshal(outputResult)
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolCallPart{
+ ToolCallID: "quux",
+ ToolName: "thwomp",
+ Input: string(inputJSON),
+ },
+ },
+ },
+ {
+ Role: fantasy.MessageRoleTool,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolResultPart{
+ ToolCallID: "quux",
+ Output: fantasy.ToolResultOutputContentText{
+ Text: string(outputJSON),
+ },
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 2)
+
+ // Check assistant message with tool call
+ assistantMsg := messages[0].OfAssistant
+ require.NotNil(t, assistantMsg)
+ require.Equal(t, "", assistantMsg.Content.OfString.Value)
+ require.Len(t, assistantMsg.ToolCalls, 1)
+
+ toolCall := assistantMsg.ToolCalls[0].OfFunction
+ require.NotNil(t, toolCall)
+ require.Equal(t, "quux", toolCall.ID)
+ require.Equal(t, "thwomp", toolCall.Function.Name)
+ require.Equal(t, string(inputJSON), toolCall.Function.Arguments)
+
+ // Check tool message
+ toolMsg := messages[1].OfTool
+ require.NotNil(t, toolMsg)
+ require.Equal(t, string(outputJSON), toolMsg.Content.OfString.Value)
+ require.Equal(t, "quux", toolMsg.ToolCallID)
+ })
+
+ t.Run("should handle different tool output types", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleTool,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolResultPart{
+ ToolCallID: "text-tool",
+ Output: fantasy.ToolResultOutputContentText{
+ Text: "Hello world",
+ },
+ },
+ fantasy.ToolResultPart{
+ ToolCallID: "error-tool",
+ Output: fantasy.ToolResultOutputContentError{
+ Error: errors.New("Something went wrong"),
+ },
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 2)
+
+ // Check first tool message (text)
+ textToolMsg := messages[0].OfTool
+ require.NotNil(t, textToolMsg)
+ require.Equal(t, "Hello world", textToolMsg.Content.OfString.Value)
+ require.Equal(t, "text-tool", textToolMsg.ToolCallID)
+
+ // Check second tool message (error)
+ errorToolMsg := messages[1].OfTool
+ require.NotNil(t, errorToolMsg)
+ require.Equal(t, "Something went wrong", errorToolMsg.Content.OfString.Value)
+ require.Equal(t, "error-tool", errorToolMsg.ToolCallID)
+ })
+}
+
+func TestToOpenAiPrompt_AssistantMessages(t *testing.T) {
+ t.Parallel()
+
+ t.Run("should handle simple text assistant messages", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello, how can I help you?"},
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 1)
+
+ assistantMsg := messages[0].OfAssistant
+ require.NotNil(t, assistantMsg)
+ require.Equal(t, "Hello, how can I help you?", assistantMsg.Content.OfString.Value)
+ })
+
+ t.Run("should handle assistant messages with mixed content", func(t *testing.T) {
+ t.Parallel()
+
+ inputArgs := map[string]any{"query": "test"}
+ inputJSON, _ := json.Marshal(inputArgs)
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Let me search for that."},
+ fantasy.ToolCallPart{
+ ToolCallID: "call-123",
+ ToolName: "search",
+ Input: string(inputJSON),
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-5")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 1)
+
+ assistantMsg := messages[0].OfAssistant
+ require.NotNil(t, assistantMsg)
+ require.Equal(t, "Let me search for that.", assistantMsg.Content.OfString.Value)
+ require.Len(t, assistantMsg.ToolCalls, 1)
+
+ toolCall := assistantMsg.ToolCalls[0].OfFunction
+ require.Equal(t, "call-123", toolCall.ID)
+ require.Equal(t, "search", toolCall.Function.Name)
+ require.Equal(t, string(inputJSON), toolCall.Function.Arguments)
+ })
+}
+
+var testPrompt = fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+}
+
+var testLogprobs = map[string]any{
+ "content": []map[string]any{
+ {
+ "token": "Hello",
+ "logprob": -0.0009994634,
+ "top_logprobs": []map[string]any{
+ {
+ "token": "Hello",
+ "logprob": -0.0009994634,
+ },
+ },
+ },
+ {
+ "token": "!",
+ "logprob": -0.13410144,
+ "top_logprobs": []map[string]any{
+ {
+ "token": "!",
+ "logprob": -0.13410144,
+ },
+ },
+ },
+ {
+ "token": " How",
+ "logprob": -0.0009250381,
+ "top_logprobs": []map[string]any{
+ {
+ "token": " How",
+ "logprob": -0.0009250381,
+ },
+ },
+ },
+ {
+ "token": " can",
+ "logprob": -0.047709424,
+ "top_logprobs": []map[string]any{
+ {
+ "token": " can",
+ "logprob": -0.047709424,
+ },
+ },
+ },
+ {
+ "token": " I",
+ "logprob": -0.000009014684,
+ "top_logprobs": []map[string]any{
+ {
+ "token": " I",
+ "logprob": -0.000009014684,
+ },
+ },
+ },
+ {
+ "token": " assist",
+ "logprob": -0.009125131,
+ "top_logprobs": []map[string]any{
+ {
+ "token": " assist",
+ "logprob": -0.009125131,
+ },
+ },
+ },
+ {
+ "token": " you",
+ "logprob": -0.0000066306106,
+ "top_logprobs": []map[string]any{
+ {
+ "token": " you",
+ "logprob": -0.0000066306106,
+ },
+ },
+ },
+ {
+ "token": " today",
+ "logprob": -0.00011093382,
+ "top_logprobs": []map[string]any{
+ {
+ "token": " today",
+ "logprob": -0.00011093382,
+ },
+ },
+ },
+ {
+ "token": "?",
+ "logprob": -0.00004596782,
+ "top_logprobs": []map[string]any{
+ {
+ "token": "?",
+ "logprob": -0.00004596782,
+ },
+ },
+ },
+ },
+}
+
+type mockServer struct {
+ server *httptest.Server
+ response map[string]any
+ calls []mockCall
+}
+
+type mockCall struct {
+ method string
+ path string
+ headers map[string]string
+ body map[string]any
+}
+
+func newMockServer() *mockServer {
+ ms := &mockServer{
+ calls: make([]mockCall, 0),
+ }
+
+ ms.server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ // Record the call
+ call := mockCall{
+ method: r.Method,
+ path: r.URL.Path,
+ headers: make(map[string]string),
+ }
+
+ for k, v := range r.Header {
+ if len(v) > 0 {
+ call.headers[k] = v[0]
+ }
+ }
+
+ // Parse request body
+ if r.Body != nil {
+ var body map[string]any
+ json.NewDecoder(r.Body).Decode(&body)
+ call.body = body
+ }
+
+ ms.calls = append(ms.calls, call)
+
+ // Return mock response
+ w.Header().Set("Content-Type", "application/json")
+ json.NewEncoder(w).Encode(ms.response)
+ }))
+
+ return ms
+}
+
+func (ms *mockServer) close() {
+ ms.server.Close()
+}
+
+func (ms *mockServer) prepareJSONResponse(opts map[string]any) {
+ // Default values
+ response := map[string]any{
+ "id": "chatcmpl-95ZTZkhr0mHNKqerQfiwkuox3PHAd",
+ "object": "chat.completion",
+ "created": 1711115037,
+ "model": "gpt-3.5-turbo-0125",
+ "choices": []map[string]any{
+ {
+ "index": 0,
+ "message": map[string]any{
+ "role": "assistant",
+ "content": "",
+ },
+ "finish_reason": "stop",
+ },
+ },
+ "usage": map[string]any{
+ "prompt_tokens": 4,
+ "total_tokens": 34,
+ "completion_tokens": 30,
+ },
+ "system_fingerprint": "fp_3bc1b5746c",
+ }
+
+ // Override with provided options
+ for k, v := range opts {
+ switch k {
+ case "content":
+ response["choices"].([]map[string]any)[0]["message"].(map[string]any)["content"] = v
+ case "tool_calls":
+ response["choices"].([]map[string]any)[0]["message"].(map[string]any)["tool_calls"] = v
+ case "function_call":
+ response["choices"].([]map[string]any)[0]["message"].(map[string]any)["function_call"] = v
+ case "annotations":
+ response["choices"].([]map[string]any)[0]["message"].(map[string]any)["annotations"] = v
+ case "usage":
+ response["usage"] = v
+ case "finish_reason":
+ response["choices"].([]map[string]any)[0]["finish_reason"] = v
+ case "id":
+ response["id"] = v
+ case "created":
+ response["created"] = v
+ case "model":
+ response["model"] = v
+ case "logprobs":
+ if v != nil {
+ response["choices"].([]map[string]any)[0]["logprobs"] = v
+ }
+ }
+ }
+
+ ms.response = response
+}
+
+func TestDoGenerate(t *testing.T) {
+ t.Parallel()
+
+ t.Run("should extract text response", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "content": "Hello, World!",
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ result, err := model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+ require.Len(t, result.Content, 1)
+
+ textContent, ok := result.Content[0].(fantasy.TextContent)
+ require.True(t, ok)
+ require.Equal(t, "Hello, World!", textContent.Text)
+ })
+
+ t.Run("should extract usage", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "usage": map[string]any{
+ "prompt_tokens": 20,
+ "total_tokens": 25,
+ "completion_tokens": 5,
+ },
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ result, err := model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+ require.Equal(t, int64(20), result.Usage.InputTokens)
+ require.Equal(t, int64(5), result.Usage.OutputTokens)
+ require.Equal(t, int64(25), result.Usage.TotalTokens)
+ })
+
+ t.Run("should send request body", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{})
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ _, err = model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "POST", call.method)
+ require.Equal(t, "/chat/completions", call.path)
+ require.Equal(t, "gpt-3.5-turbo", call.body["model"])
+
+ messages, ok := call.body["messages"].([]any)
+ require.True(t, ok)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should support partial usage", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "usage": map[string]any{
+ "prompt_tokens": 20,
+ "total_tokens": 20,
+ },
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ result, err := model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+ require.Equal(t, int64(20), result.Usage.InputTokens)
+ require.Equal(t, int64(0), result.Usage.OutputTokens)
+ require.Equal(t, int64(20), result.Usage.TotalTokens)
+ })
+
+ t.Run("should extract logprobs", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "logprobs": testLogprobs,
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ result, err := model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ LogProbs: fantasy.Opt(true),
+ }),
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result.ProviderMetadata)
+
+ openaiMeta, ok := result.ProviderMetadata["openai"].(*ProviderMetadata)
+ require.True(t, ok)
+
+ logprobs := openaiMeta.Logprobs
+ require.True(t, ok)
+ require.NotNil(t, logprobs)
+ })
+
+ t.Run("should extract finish reason", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "finish_reason": "stop",
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ result, err := model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+ require.Equal(t, fantasy.FinishReasonStop, result.FinishReason)
+ })
+
+ t.Run("should support unknown finish reason", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "finish_reason": "eos",
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ result, err := model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+ require.Equal(t, fantasy.FinishReasonUnknown, result.FinishReason)
+ })
+
+ t.Run("should pass the model and the messages", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "content": "",
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ _, err = model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "gpt-3.5-turbo", call.body["model"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should pass settings", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{})
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ _, err = model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ LogitBias: map[string]int64{
+ "50256": -100,
+ },
+ ParallelToolCalls: fantasy.Opt(false),
+ User: fantasy.Opt("test-user-id"),
+ }),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "gpt-3.5-turbo", call.body["model"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ logitBias := call.body["logit_bias"].(map[string]any)
+ require.Equal(t, float64(-100), logitBias["50256"])
+ require.Equal(t, false, call.body["parallel_tool_calls"])
+ require.Equal(t, "test-user-id", call.body["user"])
+ })
+
+ t.Run("should pass reasoningEffort setting", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "content": "",
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "o1-mini")
+
+ _, err = model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(
+ &ProviderOptions{
+ ReasoningEffort: ReasoningEffortOption(ReasoningEffortLow),
+ },
+ ),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "o1-mini", call.body["model"])
+ require.Equal(t, "low", call.body["reasoning_effort"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should pass textVerbosity setting", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "content": "",
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-4o")
+
+ _, err = model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ TextVerbosity: fantasy.Opt("low"),
+ }),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "gpt-4o", call.body["model"])
+ require.Equal(t, "low", call.body["verbosity"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should pass tools and toolChoice", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "content": "",
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ _, err = model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ Tools: []fantasy.Tool{
+ fantasy.FunctionTool{
+ Name: "test-tool",
+ InputSchema: map[string]any{
+ "type": "object",
+ "properties": map[string]any{
+ "value": map[string]any{
+ "type": "string",
+ },
+ },
+ "required": []string{"value"},
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ },
+ },
+ },
+ ToolChoice: &[]fantasy.ToolChoice{fantasy.ToolChoice("test-tool")}[0],
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "gpt-3.5-turbo", call.body["model"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ tools := call.body["tools"].([]any)
+ require.Len(t, tools, 1)
+
+ tool := tools[0].(map[string]any)
+ require.Equal(t, "function", tool["type"])
+
+ function := tool["function"].(map[string]any)
+ require.Equal(t, "test-tool", function["name"])
+ require.Equal(t, false, function["strict"])
+
+ toolChoice := call.body["tool_choice"].(map[string]any)
+ require.Equal(t, "function", toolChoice["type"])
+
+ toolChoiceFunction := toolChoice["function"].(map[string]any)
+ require.Equal(t, "test-tool", toolChoiceFunction["name"])
+ })
+
+ t.Run("should parse tool results", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "tool_calls": []map[string]any{
+ {
+ "id": "call_O17Uplv4lJvD6DVdIvFFeRMw",
+ "type": "function",
+ "function": map[string]any{
+ "name": "test-tool",
+ "arguments": `{"value":"Spark"}`,
+ },
+ },
+ },
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ result, err := model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ Tools: []fantasy.Tool{
+ fantasy.FunctionTool{
+ Name: "test-tool",
+ InputSchema: map[string]any{
+ "type": "object",
+ "properties": map[string]any{
+ "value": map[string]any{
+ "type": "string",
+ },
+ },
+ "required": []string{"value"},
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ },
+ },
+ },
+ ToolChoice: &[]fantasy.ToolChoice{fantasy.ToolChoice("test-tool")}[0],
+ })
+
+ require.NoError(t, err)
+ require.Len(t, result.Content, 1)
+
+ toolCall, ok := result.Content[0].(fantasy.ToolCallContent)
+ require.True(t, ok)
+ require.Equal(t, "call_O17Uplv4lJvD6DVdIvFFeRMw", toolCall.ToolCallID)
+ require.Equal(t, "test-tool", toolCall.ToolName)
+ require.Equal(t, `{"value":"Spark"}`, toolCall.Input)
+ })
+
+ t.Run("should handle ToolChoiceRequired", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "content": "",
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ _, err = model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ Tools: []fantasy.Tool{
+ fantasy.FunctionTool{
+ Name: "test-tool",
+ InputSchema: map[string]any{
+ "type": "object",
+ "properties": map[string]any{
+ "value": map[string]any{
+ "type": "string",
+ },
+ },
+ "required": []string{"value"},
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ },
+ },
+ },
+ ToolChoice: &[]fantasy.ToolChoice{fantasy.ToolChoiceRequired}[0],
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "gpt-3.5-turbo", call.body["model"])
+
+ // Verify tool is present
+ tools := call.body["tools"].([]any)
+ require.Len(t, tools, 1)
+
+ tool := tools[0].(map[string]any)
+ require.Equal(t, "function", tool["type"])
+
+ function := tool["function"].(map[string]any)
+ require.Equal(t, "test-tool", function["name"])
+
+ // Verify tool_choice is set to "required" (not a function name)
+ toolChoice := call.body["tool_choice"]
+ require.Equal(t, "required", toolChoice)
+ })
+
+ t.Run("should parse annotations/citations", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "content": "Based on the search results [doc1], I found information.",
+ "annotations": []map[string]any{
+ {
+ "type": "url_citation",
+ "url_citation": map[string]any{
+ "start_index": 24,
+ "end_index": 29,
+ "url": "https://example.com/doc1.pdf",
+ "title": "Document 1",
+ },
+ },
+ },
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ result, err := model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+ require.Len(t, result.Content, 2)
+
+ textContent, ok := result.Content[0].(fantasy.TextContent)
+ require.True(t, ok)
+ require.Equal(t, "Based on the search results [doc1], I found information.", textContent.Text)
+
+ sourceContent, ok := result.Content[1].(fantasy.SourceContent)
+ require.True(t, ok)
+ require.Equal(t, fantasy.SourceTypeURL, sourceContent.SourceType)
+ require.Equal(t, "https://example.com/doc1.pdf", sourceContent.URL)
+ require.Equal(t, "Document 1", sourceContent.Title)
+ require.NotEmpty(t, sourceContent.ID)
+ })
+
+ t.Run("should return cached_tokens in prompt_details_tokens", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "usage": map[string]any{
+ "prompt_tokens": 15,
+ "completion_tokens": 20,
+ "total_tokens": 35,
+ "prompt_tokens_details": map[string]any{
+ "cached_tokens": 1152,
+ },
+ },
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-4o-mini")
+
+ result, err := model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+ require.Equal(t, int64(1152), result.Usage.CacheReadTokens)
+ require.Equal(t, int64(15), result.Usage.InputTokens)
+ require.Equal(t, int64(20), result.Usage.OutputTokens)
+ require.Equal(t, int64(35), result.Usage.TotalTokens)
+ })
+
+ t.Run("should return accepted_prediction_tokens and rejected_prediction_tokens", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "usage": map[string]any{
+ "prompt_tokens": 15,
+ "completion_tokens": 20,
+ "total_tokens": 35,
+ "completion_tokens_details": map[string]any{
+ "accepted_prediction_tokens": 123,
+ "rejected_prediction_tokens": 456,
+ },
+ },
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-4o-mini")
+
+ result, err := model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+ require.NotNil(t, result.ProviderMetadata)
+
+ openaiMeta, ok := result.ProviderMetadata["openai"].(*ProviderMetadata)
+
+ require.True(t, ok)
+ require.Equal(t, int64(123), openaiMeta.AcceptedPredictionTokens)
+ require.Equal(t, int64(456), openaiMeta.RejectedPredictionTokens)
+ })
+
+ t.Run("should clear out temperature, top_p, frequency_penalty, presence_penalty for reasoning models", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{})
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "o1-preview")
+
+ result, err := model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ Temperature: &[]float64{0.5}[0],
+ TopP: &[]float64{0.7}[0],
+ FrequencyPenalty: &[]float64{0.2}[0],
+ PresencePenalty: &[]float64{0.3}[0],
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "o1-preview", call.body["model"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+
+ // These should not be present
+ require.Nil(t, call.body["temperature"])
+ require.Nil(t, call.body["top_p"])
+ require.Nil(t, call.body["frequency_penalty"])
+ require.Nil(t, call.body["presence_penalty"])
+
+ // Should have warnings
+ require.Len(t, result.Warnings, 4)
+ require.Equal(t, fantasy.CallWarningTypeUnsupportedSetting, result.Warnings[0].Type)
+ require.Equal(t, "temperature", result.Warnings[0].Setting)
+ require.Contains(t, result.Warnings[0].Details, "temperature is not supported for reasoning models")
+ })
+
+ t.Run("should convert maxOutputTokens to max_completion_tokens for reasoning models", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{})
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "o1-preview")
+
+ _, err = model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ MaxOutputTokens: &[]int64{1000}[0],
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "o1-preview", call.body["model"])
+ require.Equal(t, float64(1000), call.body["max_completion_tokens"])
+ require.Nil(t, call.body["max_tokens"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should return reasoning tokens", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "usage": map[string]any{
+ "prompt_tokens": 15,
+ "completion_tokens": 20,
+ "total_tokens": 35,
+ "completion_tokens_details": map[string]any{
+ "reasoning_tokens": 10,
+ },
+ },
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "o1-preview")
+
+ result, err := model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+ require.Equal(t, int64(15), result.Usage.InputTokens)
+ require.Equal(t, int64(20), result.Usage.OutputTokens)
+ require.Equal(t, int64(35), result.Usage.TotalTokens)
+ require.Equal(t, int64(10), result.Usage.ReasoningTokens)
+ })
+
+ t.Run("should send max_completion_tokens extension setting", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "model": "o1-preview",
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "o1-preview")
+
+ _, err = model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ MaxCompletionTokens: fantasy.Opt(int64(255)),
+ }),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "o1-preview", call.body["model"])
+ require.Equal(t, float64(255), call.body["max_completion_tokens"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should send prediction extension setting", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "content": "",
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ _, err = model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ Prediction: map[string]any{
+ "type": "content",
+ "content": "Hello, World!",
+ },
+ }),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "gpt-3.5-turbo", call.body["model"])
+
+ prediction := call.body["prediction"].(map[string]any)
+ require.Equal(t, "content", prediction["type"])
+ require.Equal(t, "Hello, World!", prediction["content"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should send store extension setting", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "content": "",
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ _, err = model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ Store: fantasy.Opt(true),
+ }),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "gpt-3.5-turbo", call.body["model"])
+ require.Equal(t, true, call.body["store"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should send metadata extension values", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "content": "",
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ _, err = model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ Metadata: map[string]any{
+ "custom": "value",
+ },
+ }),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "gpt-3.5-turbo", call.body["model"])
+
+ metadata := call.body["metadata"].(map[string]any)
+ require.Equal(t, "value", metadata["custom"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should send promptCacheKey extension value", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "content": "",
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ _, err = model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ PromptCacheKey: fantasy.Opt("test-cache-key-123"),
+ }),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "gpt-3.5-turbo", call.body["model"])
+ require.Equal(t, "test-cache-key-123", call.body["prompt_cache_key"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should send safety_identifier extension value", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "content": "",
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ _, err = model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ SafetyIdentifier: fantasy.Opt("test-safety-identifier-123"),
+ }),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "gpt-3.5-turbo", call.body["model"])
+ require.Equal(t, "test-safety-identifier-123", call.body["safety_identifier"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should remove temperature setting for search preview models", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{})
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-4o-search-preview")
+
+ result, err := model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ Temperature: &[]float64{0.7}[0],
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "gpt-4o-search-preview", call.body["model"])
+ require.Nil(t, call.body["temperature"])
+
+ require.Len(t, result.Warnings, 1)
+ require.Equal(t, fantasy.CallWarningTypeUnsupportedSetting, result.Warnings[0].Type)
+ require.Equal(t, "temperature", result.Warnings[0].Setting)
+ require.Contains(t, result.Warnings[0].Details, "search preview models")
+ })
+
+ t.Run("should send ServiceTier flex processing setting", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{
+ "content": "",
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "o3-mini")
+
+ _, err = model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ ServiceTier: fantasy.Opt("flex"),
+ }),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "o3-mini", call.body["model"])
+ require.Equal(t, "flex", call.body["service_tier"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should show warning when using flex processing with unsupported model", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{})
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-4o-mini")
+
+ result, err := model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ ServiceTier: fantasy.Opt("flex"),
+ }),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Nil(t, call.body["service_tier"])
+
+ require.Len(t, result.Warnings, 1)
+ require.Equal(t, fantasy.CallWarningTypeUnsupportedSetting, result.Warnings[0].Type)
+ require.Equal(t, "ServiceTier", result.Warnings[0].Setting)
+ require.Contains(t, result.Warnings[0].Details, "flex processing is only available")
+ })
+
+ t.Run("should send serviceTier priority processing setting", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{})
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-4o-mini")
+
+ _, err = model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ ServiceTier: fantasy.Opt("priority"),
+ }),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "gpt-4o-mini", call.body["model"])
+ require.Equal(t, "priority", call.body["service_tier"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should show warning when using priority processing with unsupported model", func(t *testing.T) {
+ t.Parallel()
+
+ server := newMockServer()
+ defer server.close()
+
+ server.prepareJSONResponse(map[string]any{})
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ result, err := model.Generate(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ ServiceTier: fantasy.Opt("priority"),
+ }),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Nil(t, call.body["service_tier"])
+
+ require.Len(t, result.Warnings, 1)
+ require.Equal(t, fantasy.CallWarningTypeUnsupportedSetting, result.Warnings[0].Type)
+ require.Equal(t, "ServiceTier", result.Warnings[0].Setting)
+ require.Contains(t, result.Warnings[0].Details, "priority processing is only available")
+ })
+}
+
+type streamingMockServer struct {
+ server *httptest.Server
+ chunks []string
+ calls []mockCall
+}
+
+func newStreamingMockServer() *streamingMockServer {
+ sms := &streamingMockServer{
+ calls: make([]mockCall, 0),
+ }
+
+ sms.server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ // Record the call
+ call := mockCall{
+ method: r.Method,
+ path: r.URL.Path,
+ headers: make(map[string]string),
+ }
+
+ for k, v := range r.Header {
+ if len(v) > 0 {
+ call.headers[k] = v[0]
+ }
+ }
+
+ // Parse request body
+ if r.Body != nil {
+ var body map[string]any
+ json.NewDecoder(r.Body).Decode(&body)
+ call.body = body
+ }
+
+ sms.calls = append(sms.calls, call)
+
+ // Set streaming headers
+ w.Header().Set("Content-Type", "text/event-stream")
+ w.Header().Set("Cache-Control", "no-cache")
+ w.Header().Set("Connection", "keep-alive")
+
+ // Add custom headers if any
+ for _, chunk := range sms.chunks {
+ if strings.HasPrefix(chunk, "HEADER:") {
+ parts := strings.SplitN(chunk[7:], ":", 2)
+ if len(parts) == 2 {
+ w.Header().Set(parts[0], parts[1])
+ }
+ continue
+ }
+ }
+
+ w.WriteHeader(http.StatusOK)
+
+ // Write chunks
+ for _, chunk := range sms.chunks {
+ if strings.HasPrefix(chunk, "HEADER:") {
+ continue
+ }
+ w.Write([]byte(chunk))
+ if f, ok := w.(http.Flusher); ok {
+ f.Flush()
+ }
+ }
+ }))
+
+ return sms
+}
+
+func (sms *streamingMockServer) close() {
+ sms.server.Close()
+}
+
+func (sms *streamingMockServer) prepareStreamResponse(opts map[string]any) {
+ content := []string{}
+ if c, ok := opts["content"].([]string); ok {
+ content = c
+ }
+
+ usage := map[string]any{
+ "prompt_tokens": 17,
+ "total_tokens": 244,
+ "completion_tokens": 227,
+ }
+ if u, ok := opts["usage"].(map[string]any); ok {
+ usage = u
+ }
+
+ logprobs := map[string]any{}
+ if l, ok := opts["logprobs"].(map[string]any); ok {
+ logprobs = l
+ }
+
+ finishReason := "stop"
+ if fr, ok := opts["finish_reason"].(string); ok {
+ finishReason = fr
+ }
+
+ model := "gpt-3.5-turbo-0613"
+ if m, ok := opts["model"].(string); ok {
+ model = m
+ }
+
+ headers := map[string]string{}
+ if h, ok := opts["headers"].(map[string]string); ok {
+ headers = h
+ }
+
+ chunks := []string{}
+
+ // Add custom headers
+ for k, v := range headers {
+ chunks = append(chunks, "HEADER:"+k+":"+v)
+ }
+
+ // Initial chunk with role
+ initialChunk := map[string]any{
+ "id": "chatcmpl-96aZqmeDpA9IPD6tACY8djkMsJCMP",
+ "object": "chat.completion.chunk",
+ "created": 1702657020,
+ "model": model,
+ "system_fingerprint": nil,
+ "choices": []map[string]any{
+ {
+ "index": 0,
+ "delta": map[string]any{
+ "role": "assistant",
+ "content": "",
+ },
+ "finish_reason": nil,
+ },
+ },
+ }
+ initialData, _ := json.Marshal(initialChunk)
+ chunks = append(chunks, "data: "+string(initialData)+"\n\n")
+
+ // Content chunks
+ for i, text := range content {
+ contentChunk := map[string]any{
+ "id": "chatcmpl-96aZqmeDpA9IPD6tACY8djkMsJCMP",
+ "object": "chat.completion.chunk",
+ "created": 1702657020,
+ "model": model,
+ "system_fingerprint": nil,
+ "choices": []map[string]any{
+ {
+ "index": 1,
+ "delta": map[string]any{
+ "content": text,
+ },
+ "finish_reason": nil,
+ },
+ },
+ }
+ contentData, _ := json.Marshal(contentChunk)
+ chunks = append(chunks, "data: "+string(contentData)+"\n\n")
+
+ // Add annotations if this is the last content chunk and we have annotations
+ if i == len(content)-1 {
+ if annotations, ok := opts["annotations"].([]map[string]any); ok {
+ annotationChunk := map[string]any{
+ "id": "chatcmpl-96aZqmeDpA9IPD6tACY8djkMsJCMP",
+ "object": "chat.completion.chunk",
+ "created": 1702657020,
+ "model": model,
+ "system_fingerprint": nil,
+ "choices": []map[string]any{
+ {
+ "index": 1,
+ "delta": map[string]any{
+ "annotations": annotations,
+ },
+ "finish_reason": nil,
+ },
+ },
+ }
+ annotationData, _ := json.Marshal(annotationChunk)
+ chunks = append(chunks, "data: "+string(annotationData)+"\n\n")
+ }
+ }
+ }
+
+ // Finish chunk
+ finishChunk := map[string]any{
+ "id": "chatcmpl-96aZqmeDpA9IPD6tACY8djkMsJCMP",
+ "object": "chat.completion.chunk",
+ "created": 1702657020,
+ "model": model,
+ "system_fingerprint": nil,
+ "choices": []map[string]any{
+ {
+ "index": 0,
+ "delta": map[string]any{},
+ "finish_reason": finishReason,
+ },
+ },
+ }
+
+ if len(logprobs) > 0 {
+ finishChunk["choices"].([]map[string]any)[0]["logprobs"] = logprobs
+ }
+
+ finishData, _ := json.Marshal(finishChunk)
+ chunks = append(chunks, "data: "+string(finishData)+"\n\n")
+
+ // Usage chunk
+ usageChunk := map[string]any{
+ "id": "chatcmpl-96aZqmeDpA9IPD6tACY8djkMsJCMP",
+ "object": "chat.completion.chunk",
+ "created": 1702657020,
+ "model": model,
+ "system_fingerprint": "fp_3bc1b5746c",
+ "choices": []map[string]any{},
+ "usage": usage,
+ }
+ usageData, _ := json.Marshal(usageChunk)
+ chunks = append(chunks, "data: "+string(usageData)+"\n\n")
+
+ // Done
+ chunks = append(chunks, "data: [DONE]\n\n")
+
+ sms.chunks = chunks
+}
+
+func (sms *streamingMockServer) prepareToolStreamResponse() {
+ chunks := []string{
+ `data: {"id":"chatcmpl-96aZqmeDpA9IPD6tACY8djkMsJCMP","object":"chat.completion.chunk","created":1711357598,"model":"gpt-3.5-turbo-0125","system_fingerprint":"fp_3bc1b5746c","choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"call_O17Uplv4lJvD6DVdIvFFeRMw","type":"function","function":{"name":"test-tool","arguments":""}}]},"logprobs":null,"finish_reason":null}]}` + "\n\n",
+ `data: {"id":"chatcmpl-96aZqmeDpA9IPD6tACY8djkMsJCMP","object":"chat.completion.chunk","created":1711357598,"model":"gpt-3.5-turbo-0125","system_fingerprint":"fp_3bc1b5746c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\""}}]},"logprobs":null,"finish_reason":null}]}` + "\n\n",
+ `data: {"id":"chatcmpl-96aZqmeDpA9IPD6tACY8djkMsJCMP","object":"chat.completion.chunk","created":1711357598,"model":"gpt-3.5-turbo-0125","system_fingerprint":"fp_3bc1b5746c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"value"}}]},"logprobs":null,"finish_reason":null}]}` + "\n\n",
+ `data: {"id":"chatcmpl-96aZqmeDpA9IPD6tACY8djkMsJCMP","object":"chat.completion.chunk","created":1711357598,"model":"gpt-3.5-turbo-0125","system_fingerprint":"fp_3bc1b5746c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"logprobs":null,"finish_reason":null}]}` + "\n\n",
+ `data: {"id":"chatcmpl-96aZqmeDpA9IPD6tACY8djkMsJCMP","object":"chat.completion.chunk","created":1711357598,"model":"gpt-3.5-turbo-0125","system_fingerprint":"fp_3bc1b5746c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Spark"}}]},"logprobs":null,"finish_reason":null}]}` + "\n\n",
+ `data: {"id":"chatcmpl-96aZqmeDpA9IPD6tACY8djkMsJCMP","object":"chat.completion.chunk","created":1711357598,"model":"gpt-3.5-turbo-0125","system_fingerprint":"fp_3bc1b5746c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le"}}]},"logprobs":null,"finish_reason":null}]}` + "\n\n",
+ `data: {"id":"chatcmpl-96aZqmeDpA9IPD6tACY8djkMsJCMP","object":"chat.completion.chunk","created":1711357598,"model":"gpt-3.5-turbo-0125","system_fingerprint":"fp_3bc1b5746c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" Day"}}]},"logprobs":null,"finish_reason":null}]}` + "\n\n",
+ `data: {"id":"chatcmpl-96aZqmeDpA9IPD6tACY8djkMsJCMP","object":"chat.completion.chunk","created":1711357598,"model":"gpt-3.5-turbo-0125","system_fingerprint":"fp_3bc1b5746c","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"}"}}]},"logprobs":null,"finish_reason":null}]}` + "\n\n",
+ `data: {"id":"chatcmpl-96aZqmeDpA9IPD6tACY8djkMsJCMP","object":"chat.completion.chunk","created":1711357598,"model":"gpt-3.5-turbo-0125","system_fingerprint":"fp_3bc1b5746c","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}]}` + "\n\n",
+ `data: {"id":"chatcmpl-96aZqmeDpA9IPD6tACY8djkMsJCMP","object":"chat.completion.chunk","created":1711357598,"model":"gpt-3.5-turbo-0125","system_fingerprint":"fp_3bc1b5746c","choices":[],"usage":{"prompt_tokens":53,"completion_tokens":17,"total_tokens":70}}` + "\n\n",
+ "data: [DONE]\n\n",
+ }
+ sms.chunks = chunks
+}
+
+func (sms *streamingMockServer) prepareErrorStreamResponse() {
+ chunks := []string{
+ `data: {"error":{"message": "The server had an error processing your request. Sorry about that! You can retry your request, or contact us through our help center at help.openai.com if you keep seeing this error.","type":"server_error","param":null,"code":null}}` + "\n\n",
+ "data: [DONE]\n\n",
+ }
+ sms.chunks = chunks
+}
+
+func collectStreamParts(stream fantasy.StreamResponse) ([]fantasy.StreamPart, error) {
+ var parts []fantasy.StreamPart
+ for part := range stream {
+ parts = append(parts, part)
+ if part.Type == fantasy.StreamPartTypeError {
+ break
+ }
+ if part.Type == fantasy.StreamPartTypeFinish {
+ break
+ }
+ }
+ return parts, nil
+}
+
+func TestDoStream(t *testing.T) {
+ t.Parallel()
+
+ t.Run("should stream text deltas", func(t *testing.T) {
+ t.Parallel()
+
+ server := newStreamingMockServer()
+ defer server.close()
+
+ server.prepareStreamResponse(map[string]any{
+ "content": []string{"Hello", ", ", "World!"},
+ "finish_reason": "stop",
+ "usage": map[string]any{
+ "prompt_tokens": 17,
+ "total_tokens": 244,
+ "completion_tokens": 227,
+ },
+ "logprobs": testLogprobs,
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ stream, err := model.Stream(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+
+ parts, err := collectStreamParts(stream)
+ require.NoError(t, err)
+
+ // Verify stream structure
+ require.True(t, len(parts) >= 4) // text-start, deltas, text-end, finish
+
+ // Find text parts
+ textStart, textEnd, finish := -1, -1, -1
+ var deltas []string
+
+ for i, part := range parts {
+ switch part.Type {
+ case fantasy.StreamPartTypeTextStart:
+ textStart = i
+ case fantasy.StreamPartTypeTextDelta:
+ deltas = append(deltas, part.Delta)
+ case fantasy.StreamPartTypeTextEnd:
+ textEnd = i
+ case fantasy.StreamPartTypeFinish:
+ finish = i
+ }
+ }
+
+ require.NotEqual(t, -1, textStart)
+ require.NotEqual(t, -1, textEnd)
+ require.NotEqual(t, -1, finish)
+ require.Equal(t, []string{"Hello", ", ", "World!"}, deltas)
+
+ // Check finish part
+ finishPart := parts[finish]
+ require.Equal(t, fantasy.FinishReasonStop, finishPart.FinishReason)
+ require.Equal(t, int64(17), finishPart.Usage.InputTokens)
+ require.Equal(t, int64(227), finishPart.Usage.OutputTokens)
+ require.Equal(t, int64(244), finishPart.Usage.TotalTokens)
+ })
+
+ t.Run("should stream tool deltas", func(t *testing.T) {
+ t.Parallel()
+
+ server := newStreamingMockServer()
+ defer server.close()
+
+ server.prepareToolStreamResponse()
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ stream, err := model.Stream(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ Tools: []fantasy.Tool{
+ fantasy.FunctionTool{
+ Name: "test-tool",
+ InputSchema: map[string]any{
+ "type": "object",
+ "properties": map[string]any{
+ "value": map[string]any{
+ "type": "string",
+ },
+ },
+ "required": []string{"value"},
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ },
+ },
+ },
+ })
+
+ require.NoError(t, err)
+
+ parts, err := collectStreamParts(stream)
+ require.NoError(t, err)
+
+ // Find tool-related parts
+ toolInputStart, toolInputEnd, toolCall := -1, -1, -1
+ var toolDeltas []string
+
+ for i, part := range parts {
+ switch part.Type {
+ case fantasy.StreamPartTypeToolInputStart:
+ toolInputStart = i
+ require.Equal(t, "call_O17Uplv4lJvD6DVdIvFFeRMw", part.ID)
+ require.Equal(t, "test-tool", part.ToolCallName)
+ case fantasy.StreamPartTypeToolInputDelta:
+ toolDeltas = append(toolDeltas, part.Delta)
+ case fantasy.StreamPartTypeToolInputEnd:
+ toolInputEnd = i
+ case fantasy.StreamPartTypeToolCall:
+ toolCall = i
+ require.Equal(t, "call_O17Uplv4lJvD6DVdIvFFeRMw", part.ID)
+ require.Equal(t, "test-tool", part.ToolCallName)
+ require.Equal(t, `{"value":"Sparkle Day"}`, part.ToolCallInput)
+ }
+ }
+
+ require.NotEqual(t, -1, toolInputStart)
+ require.NotEqual(t, -1, toolInputEnd)
+ require.NotEqual(t, -1, toolCall)
+
+ // Verify tool deltas combine to form the complete input
+ var fullInput strings.Builder
+ for _, delta := range toolDeltas {
+ fullInput.WriteString(delta)
+ }
+ require.Equal(t, `{"value":"Sparkle Day"}`, fullInput.String())
+ })
+
+ t.Run("should stream annotations/citations", func(t *testing.T) {
+ t.Parallel()
+
+ server := newStreamingMockServer()
+ defer server.close()
+
+ server.prepareStreamResponse(map[string]any{
+ "content": []string{"Based on search results"},
+ "annotations": []map[string]any{
+ {
+ "type": "url_citation",
+ "url_citation": map[string]any{
+ "start_index": 24,
+ "end_index": 29,
+ "url": "https://example.com/doc1.pdf",
+ "title": "Document 1",
+ },
+ },
+ },
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ stream, err := model.Stream(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+
+ parts, err := collectStreamParts(stream)
+ require.NoError(t, err)
+
+ // Find source part
+ var sourcePart *fantasy.StreamPart
+ for _, part := range parts {
+ if part.Type == fantasy.StreamPartTypeSource {
+ sourcePart = &part
+ break
+ }
+ }
+
+ require.NotNil(t, sourcePart)
+ require.Equal(t, fantasy.SourceTypeURL, sourcePart.SourceType)
+ require.Equal(t, "https://example.com/doc1.pdf", sourcePart.URL)
+ require.Equal(t, "Document 1", sourcePart.Title)
+ require.NotEmpty(t, sourcePart.ID)
+ })
+
+ t.Run("should handle error stream parts", func(t *testing.T) {
+ t.Parallel()
+
+ server := newStreamingMockServer()
+ defer server.close()
+
+ server.prepareErrorStreamResponse()
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ stream, err := model.Stream(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+
+ parts, err := collectStreamParts(stream)
+ require.NoError(t, err)
+
+ // Should have error and finish parts
+ require.True(t, len(parts) >= 1)
+
+ // Find error part
+ var errorPart *fantasy.StreamPart
+ for _, part := range parts {
+ if part.Type == fantasy.StreamPartTypeError {
+ errorPart = &part
+ break
+ }
+ }
+
+ require.NotNil(t, errorPart)
+ require.NotNil(t, errorPart.Error)
+ })
+
+ t.Run("should send request body", func(t *testing.T) {
+ t.Parallel()
+
+ server := newStreamingMockServer()
+ defer server.close()
+
+ server.prepareStreamResponse(map[string]any{
+ "content": []string{},
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ _, err = model.Stream(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "POST", call.method)
+ require.Equal(t, "/chat/completions", call.path)
+ require.Equal(t, "gpt-3.5-turbo", call.body["model"])
+ require.Equal(t, true, call.body["stream"])
+
+ streamOptions := call.body["stream_options"].(map[string]any)
+ require.Equal(t, true, streamOptions["include_usage"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should return cached tokens in providerMetadata", func(t *testing.T) {
+ t.Parallel()
+
+ server := newStreamingMockServer()
+ defer server.close()
+
+ server.prepareStreamResponse(map[string]any{
+ "content": []string{},
+ "usage": map[string]any{
+ "prompt_tokens": 15,
+ "completion_tokens": 20,
+ "total_tokens": 35,
+ "prompt_tokens_details": map[string]any{
+ "cached_tokens": 1152,
+ },
+ },
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ stream, err := model.Stream(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+
+ parts, err := collectStreamParts(stream)
+ require.NoError(t, err)
+
+ // Find finish part
+ var finishPart *fantasy.StreamPart
+ for _, part := range parts {
+ if part.Type == fantasy.StreamPartTypeFinish {
+ finishPart = &part
+ break
+ }
+ }
+
+ require.NotNil(t, finishPart)
+ require.Equal(t, int64(1152), finishPart.Usage.CacheReadTokens)
+ require.Equal(t, int64(15), finishPart.Usage.InputTokens)
+ require.Equal(t, int64(20), finishPart.Usage.OutputTokens)
+ require.Equal(t, int64(35), finishPart.Usage.TotalTokens)
+ })
+
+ t.Run("should return accepted_prediction_tokens and rejected_prediction_tokens", func(t *testing.T) {
+ t.Parallel()
+
+ server := newStreamingMockServer()
+ defer server.close()
+
+ server.prepareStreamResponse(map[string]any{
+ "content": []string{},
+ "usage": map[string]any{
+ "prompt_tokens": 15,
+ "completion_tokens": 20,
+ "total_tokens": 35,
+ "completion_tokens_details": map[string]any{
+ "accepted_prediction_tokens": 123,
+ "rejected_prediction_tokens": 456,
+ },
+ },
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ stream, err := model.Stream(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+
+ parts, err := collectStreamParts(stream)
+ require.NoError(t, err)
+
+ // Find finish part
+ var finishPart *fantasy.StreamPart
+ for _, part := range parts {
+ if part.Type == fantasy.StreamPartTypeFinish {
+ finishPart = &part
+ break
+ }
+ }
+
+ require.NotNil(t, finishPart)
+ require.NotNil(t, finishPart.ProviderMetadata)
+
+ openaiMeta, ok := finishPart.ProviderMetadata["openai"].(*ProviderMetadata)
+ require.True(t, ok)
+ require.Equal(t, int64(123), openaiMeta.AcceptedPredictionTokens)
+ require.Equal(t, int64(456), openaiMeta.RejectedPredictionTokens)
+ })
+
+ t.Run("should send store extension setting", func(t *testing.T) {
+ t.Parallel()
+
+ server := newStreamingMockServer()
+ defer server.close()
+
+ server.prepareStreamResponse(map[string]any{
+ "content": []string{},
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ _, err = model.Stream(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ Store: fantasy.Opt(true),
+ }),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "gpt-3.5-turbo", call.body["model"])
+ require.Equal(t, true, call.body["stream"])
+ require.Equal(t, true, call.body["store"])
+
+ streamOptions := call.body["stream_options"].(map[string]any)
+ require.Equal(t, true, streamOptions["include_usage"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should send metadata extension values", func(t *testing.T) {
+ t.Parallel()
+
+ server := newStreamingMockServer()
+ defer server.close()
+
+ server.prepareStreamResponse(map[string]any{
+ "content": []string{},
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-3.5-turbo")
+
+ _, err = model.Stream(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ Metadata: map[string]any{
+ "custom": "value",
+ },
+ }),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "gpt-3.5-turbo", call.body["model"])
+ require.Equal(t, true, call.body["stream"])
+
+ metadata := call.body["metadata"].(map[string]any)
+ require.Equal(t, "value", metadata["custom"])
+
+ streamOptions := call.body["stream_options"].(map[string]any)
+ require.Equal(t, true, streamOptions["include_usage"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should send serviceTier flex processing setting in streaming", func(t *testing.T) {
+ t.Parallel()
+
+ server := newStreamingMockServer()
+ defer server.close()
+
+ server.prepareStreamResponse(map[string]any{
+ "content": []string{},
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "o3-mini")
+
+ _, err = model.Stream(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ ServiceTier: fantasy.Opt("flex"),
+ }),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "o3-mini", call.body["model"])
+ require.Equal(t, "flex", call.body["service_tier"])
+ require.Equal(t, true, call.body["stream"])
+
+ streamOptions := call.body["stream_options"].(map[string]any)
+ require.Equal(t, true, streamOptions["include_usage"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should send serviceTier priority processing setting in streaming", func(t *testing.T) {
+ t.Parallel()
+
+ server := newStreamingMockServer()
+ defer server.close()
+
+ server.prepareStreamResponse(map[string]any{
+ "content": []string{},
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "gpt-4o-mini")
+
+ _, err = model.Stream(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ ProviderOptions: NewProviderOptions(&ProviderOptions{
+ ServiceTier: fantasy.Opt("priority"),
+ }),
+ })
+
+ require.NoError(t, err)
+ require.Len(t, server.calls, 1)
+
+ call := server.calls[0]
+ require.Equal(t, "gpt-4o-mini", call.body["model"])
+ require.Equal(t, "priority", call.body["service_tier"])
+ require.Equal(t, true, call.body["stream"])
+
+ streamOptions := call.body["stream_options"].(map[string]any)
+ require.Equal(t, true, streamOptions["include_usage"])
+
+ messages := call.body["messages"].([]any)
+ require.Len(t, messages, 1)
+
+ message := messages[0].(map[string]any)
+ require.Equal(t, "user", message["role"])
+ require.Equal(t, "Hello", message["content"])
+ })
+
+ t.Run("should stream text delta for reasoning models", func(t *testing.T) {
+ t.Parallel()
+
+ server := newStreamingMockServer()
+ defer server.close()
+
+ server.prepareStreamResponse(map[string]any{
+ "content": []string{"Hello, World!"},
+ "model": "o1-preview",
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "o1-preview")
+
+ stream, err := model.Stream(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+
+ parts, err := collectStreamParts(stream)
+ require.NoError(t, err)
+
+ // Find text parts
+ var textDeltas []string
+ for _, part := range parts {
+ if part.Type == fantasy.StreamPartTypeTextDelta {
+ textDeltas = append(textDeltas, part.Delta)
+ }
+ }
+
+ // Should contain the text content (without empty delta)
+ require.Equal(t, []string{"Hello, World!"}, textDeltas)
+ })
+
+ t.Run("should send reasoning tokens", func(t *testing.T) {
+ t.Parallel()
+
+ server := newStreamingMockServer()
+ defer server.close()
+
+ server.prepareStreamResponse(map[string]any{
+ "content": []string{"Hello, World!"},
+ "model": "o1-preview",
+ "usage": map[string]any{
+ "prompt_tokens": 15,
+ "completion_tokens": 20,
+ "total_tokens": 35,
+ "completion_tokens_details": map[string]any{
+ "reasoning_tokens": 10,
+ },
+ },
+ })
+
+ provider, err := New(
+ WithAPIKey("test-api-key"),
+ WithBaseURL(server.server.URL),
+ )
+ require.NoError(t, err)
+ model, _ := provider.LanguageModel(t.Context(), "o1-preview")
+
+ stream, err := model.Stream(context.Background(), fantasy.Call{
+ Prompt: testPrompt,
+ })
+
+ require.NoError(t, err)
+
+ parts, err := collectStreamParts(stream)
+ require.NoError(t, err)
+
+ // Find finish part
+ var finishPart *fantasy.StreamPart
+ for _, part := range parts {
+ if part.Type == fantasy.StreamPartTypeFinish {
+ finishPart = &part
+ break
+ }
+ }
+
+ require.NotNil(t, finishPart)
+ require.Equal(t, int64(15), finishPart.Usage.InputTokens)
+ require.Equal(t, int64(20), finishPart.Usage.OutputTokens)
+ require.Equal(t, int64(35), finishPart.Usage.TotalTokens)
+ require.Equal(t, int64(10), finishPart.Usage.ReasoningTokens)
+ })
+}
+
+func TestDefaultToPrompt_DropsEmptyMessages(t *testing.T) {
+ t.Parallel()
+
+ t.Run("should drop truly empty assistant messages", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{},
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-4")
+
+ require.Len(t, messages, 1, "should only have user message")
+ require.Len(t, warnings, 1)
+ require.Equal(t, fantasy.CallWarningTypeOther, warnings[0].Type)
+ require.Contains(t, warnings[0].Message, "dropping empty assistant message")
+ })
+
+ t.Run("should keep assistant messages with text content", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hi there!"},
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-4")
+
+ require.Len(t, messages, 2, "should have both user and assistant messages")
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should keep assistant messages with tool calls", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "What's the weather?"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolCallPart{
+ ToolCallID: "call_123",
+ ToolName: "get_weather",
+ Input: `{"location":"NYC"}`,
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-4")
+
+ require.Len(t, messages, 2, "should have both user and assistant messages")
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should drop user messages without visible content", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ Data: []byte("not supported"),
+ MediaType: "application/unknown",
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-4")
+
+ require.Empty(t, messages)
+ require.Len(t, warnings, 2) // One for unsupported type, one for empty message
+ require.Contains(t, warnings[1].Message, "dropping empty user message")
+ })
+
+ t.Run("should keep user messages with image content", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ Data: []byte{0x01, 0x02, 0x03},
+ MediaType: "image/png",
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-4")
+
+ require.Len(t, messages, 1)
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should keep user messages with tool results", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleTool,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolResultPart{
+ ToolCallID: "call_123",
+ Output: fantasy.ToolResultOutputContentText{Text: "done"},
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-4")
+
+ require.Len(t, messages, 1)
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should keep user messages with tool error results", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleTool,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolResultPart{
+ ToolCallID: "call_456",
+ Output: fantasy.ToolResultOutputContentError{Error: errors.New("boom")},
+ },
+ },
+ },
+ }
+
+ messages, warnings := DefaultToPrompt(prompt, "openai", "gpt-4")
+
+ require.Len(t, messages, 1)
+ require.Empty(t, warnings)
+ })
+}
+
+func TestResponsesToPrompt_DropsEmptyMessages(t *testing.T) {
+ t.Parallel()
+
+ t.Run("should drop truly empty assistant messages", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{},
+ },
+ }
+
+ input, warnings := toResponsesPrompt(prompt, "system")
+
+ require.Len(t, input, 1, "should only have user message")
+ require.Len(t, warnings, 1)
+ require.Equal(t, fantasy.CallWarningTypeOther, warnings[0].Type)
+ require.Contains(t, warnings[0].Message, "dropping empty assistant message")
+ })
+
+ t.Run("should keep assistant messages with text content", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hi there!"},
+ },
+ },
+ }
+
+ input, warnings := toResponsesPrompt(prompt, "system")
+
+ require.Len(t, input, 2, "should have both user and assistant messages")
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should keep assistant messages with tool calls", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "What's the weather?"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolCallPart{
+ ToolCallID: "call_123",
+ ToolName: "get_weather",
+ Input: `{"location":"NYC"}`,
+ },
+ },
+ },
+ }
+
+ input, warnings := toResponsesPrompt(prompt, "system")
+
+ require.Len(t, input, 2, "should have both user and assistant messages")
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should drop user messages without visible content", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ Data: []byte("not supported"),
+ MediaType: "application/unknown",
+ },
+ },
+ },
+ }
+
+ input, warnings := toResponsesPrompt(prompt, "system")
+
+ require.Empty(t, input)
+ require.Len(t, warnings, 2) // One for unsupported type, one for empty message
+ require.Contains(t, warnings[1].Message, "dropping empty user message")
+ })
+
+ t.Run("should keep user messages with image content", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ Data: []byte{0x01, 0x02, 0x03},
+ MediaType: "image/png",
+ },
+ },
+ },
+ }
+
+ input, warnings := toResponsesPrompt(prompt, "system")
+
+ require.Len(t, input, 1)
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should keep user messages with tool results", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleTool,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolResultPart{
+ ToolCallID: "call_123",
+ Output: fantasy.ToolResultOutputContentText{Text: "done"},
+ },
+ },
+ },
+ }
+
+ input, warnings := toResponsesPrompt(prompt, "system")
+
+ require.Len(t, input, 1)
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should keep user messages with tool error results", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleTool,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolResultPart{
+ ToolCallID: "call_456",
+ Output: fantasy.ToolResultOutputContentError{Error: errors.New("boom")},
+ },
+ },
+ },
+ }
+
+ input, warnings := toResponsesPrompt(prompt, "system")
+
+ require.Len(t, input, 1)
+ require.Empty(t, warnings)
+ })
+}
diff --git a/internal/fantasy/providers/openai/provider_options.go b/internal/fantasy/providers/openai/provider_options.go
new file mode 100644
index 000000000..adb02fbd1
--- /dev/null
+++ b/internal/fantasy/providers/openai/provider_options.go
@@ -0,0 +1,174 @@
+// Package openai provides an implementation of the fantasy AI SDK for OpenAI's language models.
+package openai
+
+import (
+ "encoding/json"
+
+ "charm.land/fantasy"
+ "github.com/openai/openai-go/v2"
+)
+
+// ReasoningEffort represents the reasoning effort level for OpenAI models.
+type ReasoningEffort string
+
+const (
+ // ReasoningEffortMinimal represents minimal reasoning effort.
+ ReasoningEffortMinimal ReasoningEffort = "minimal"
+ // ReasoningEffortLow represents low reasoning effort.
+ ReasoningEffortLow ReasoningEffort = "low"
+ // ReasoningEffortMedium represents medium reasoning effort.
+ ReasoningEffortMedium ReasoningEffort = "medium"
+ // ReasoningEffortHigh represents high reasoning effort.
+ ReasoningEffortHigh ReasoningEffort = "high"
+)
+
+// Global type identifiers for OpenAI-specific provider data.
+const (
+ TypeProviderOptions = Name + ".options"
+ TypeProviderFileOptions = Name + ".file_options"
+ TypeProviderMetadata = Name + ".metadata"
+)
+
+// Register OpenAI provider-specific types with the global registry.
+func init() {
+ fantasy.RegisterProviderType(TypeProviderOptions, func(data []byte) (fantasy.ProviderOptionsData, error) {
+ var v ProviderOptions
+ if err := json.Unmarshal(data, &v); err != nil {
+ return nil, err
+ }
+ return &v, nil
+ })
+ fantasy.RegisterProviderType(TypeProviderFileOptions, func(data []byte) (fantasy.ProviderOptionsData, error) {
+ var v ProviderFileOptions
+ if err := json.Unmarshal(data, &v); err != nil {
+ return nil, err
+ }
+ return &v, nil
+ })
+ fantasy.RegisterProviderType(TypeProviderMetadata, func(data []byte) (fantasy.ProviderOptionsData, error) {
+ var v ProviderMetadata
+ if err := json.Unmarshal(data, &v); err != nil {
+ return nil, err
+ }
+ return &v, nil
+ })
+}
+
+// ProviderMetadata represents additional metadata from OpenAI provider.
+type ProviderMetadata struct {
+ Logprobs []openai.ChatCompletionTokenLogprob `json:"logprobs"`
+ AcceptedPredictionTokens int64 `json:"accepted_prediction_tokens"`
+ RejectedPredictionTokens int64 `json:"rejected_prediction_tokens"`
+}
+
+// Options implements the ProviderOptions interface.
+func (*ProviderMetadata) Options() {}
+
+// MarshalJSON implements custom JSON marshaling with type info for ProviderMetadata.
+func (m ProviderMetadata) MarshalJSON() ([]byte, error) {
+ type plain ProviderMetadata
+ return fantasy.MarshalProviderType(TypeProviderMetadata, plain(m))
+}
+
+// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderMetadata.
+func (m *ProviderMetadata) UnmarshalJSON(data []byte) error {
+ type plain ProviderMetadata
+ var p plain
+ if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+ return err
+ }
+ *m = ProviderMetadata(p)
+ return nil
+}
+
+// ProviderOptions represents additional options for OpenAI provider.
+type ProviderOptions struct {
+ LogitBias map[string]int64 `json:"logit_bias"`
+ LogProbs *bool `json:"log_probs"`
+ TopLogProbs *int64 `json:"top_log_probs"`
+ ParallelToolCalls *bool `json:"parallel_tool_calls"`
+ User *string `json:"user"`
+ ReasoningEffort *ReasoningEffort `json:"reasoning_effort"`
+ MaxCompletionTokens *int64 `json:"max_completion_tokens"`
+ TextVerbosity *string `json:"text_verbosity"`
+ Prediction map[string]any `json:"prediction"`
+ Store *bool `json:"store"`
+ Metadata map[string]any `json:"metadata"`
+ PromptCacheKey *string `json:"prompt_cache_key"`
+ SafetyIdentifier *string `json:"safety_identifier"`
+ ServiceTier *string `json:"service_tier"`
+ StructuredOutputs *bool `json:"structured_outputs"`
+}
+
+// Options implements the ProviderOptions interface.
+func (*ProviderOptions) Options() {}
+
+// MarshalJSON implements custom JSON marshaling with type info for ProviderOptions.
+func (o ProviderOptions) MarshalJSON() ([]byte, error) {
+ type plain ProviderOptions
+ return fantasy.MarshalProviderType(TypeProviderOptions, plain(o))
+}
+
+// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderOptions.
+func (o *ProviderOptions) UnmarshalJSON(data []byte) error {
+ type plain ProviderOptions
+ var p plain
+ if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+ return err
+ }
+ *o = ProviderOptions(p)
+ return nil
+}
+
+// ProviderFileOptions represents file options for OpenAI provider.
+type ProviderFileOptions struct {
+ ImageDetail string `json:"image_detail"`
+}
+
+// Options implements the ProviderOptions interface.
+func (*ProviderFileOptions) Options() {}
+
+// MarshalJSON implements custom JSON marshaling with type info for ProviderFileOptions.
+func (o ProviderFileOptions) MarshalJSON() ([]byte, error) {
+ type plain ProviderFileOptions
+ return fantasy.MarshalProviderType(TypeProviderFileOptions, plain(o))
+}
+
+// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderFileOptions.
+func (o *ProviderFileOptions) UnmarshalJSON(data []byte) error {
+ type plain ProviderFileOptions
+ var p plain
+ if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+ return err
+ }
+ *o = ProviderFileOptions(p)
+ return nil
+}
+
+// ReasoningEffortOption creates a pointer to a ReasoningEffort value.
+func ReasoningEffortOption(e ReasoningEffort) *ReasoningEffort {
+ return &e
+}
+
+// NewProviderOptions creates new provider options for OpenAI.
+func NewProviderOptions(opts *ProviderOptions) fantasy.ProviderOptions {
+ return fantasy.ProviderOptions{
+ Name: opts,
+ }
+}
+
+// NewProviderFileOptions creates new file options for OpenAI.
+func NewProviderFileOptions(opts *ProviderFileOptions) fantasy.ProviderOptions {
+ return fantasy.ProviderOptions{
+ Name: opts,
+ }
+}
+
+// ParseOptions parses provider options from a map.
+func ParseOptions(data map[string]any) (*ProviderOptions, error) {
+ var options ProviderOptions
+ if err := fantasy.ParseOptions(data, &options); err != nil {
+ return nil, err
+ }
+ return &options, nil
+}
diff --git a/internal/fantasy/providers/openai/responses_language_model.go b/internal/fantasy/providers/openai/responses_language_model.go
new file mode 100644
index 000000000..39ee8e427
--- /dev/null
+++ b/internal/fantasy/providers/openai/responses_language_model.go
@@ -0,0 +1,1342 @@
+package openai
+
+import (
+ "context"
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "reflect"
+ "strings"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/object"
+ "charm.land/fantasy/schema"
+ "github.com/google/uuid"
+ "github.com/openai/openai-go/v2"
+ "github.com/openai/openai-go/v2/packages/param"
+ "github.com/openai/openai-go/v2/responses"
+ "github.com/openai/openai-go/v2/shared"
+)
+
+const topLogprobsMax = 20
+
+type responsesLanguageModel struct {
+ provider string
+ modelID string
+ client openai.Client
+ objectMode fantasy.ObjectMode
+}
+
+// newResponsesLanguageModel implements a responses api model
+// INFO: (kujtim) currently we do not support stored parameter we default it to false.
+func newResponsesLanguageModel(modelID string, provider string, client openai.Client, objectMode fantasy.ObjectMode) responsesLanguageModel {
+ return responsesLanguageModel{
+ modelID: modelID,
+ provider: provider,
+ client: client,
+ objectMode: objectMode,
+ }
+}
+
+func (o responsesLanguageModel) Model() string {
+ return o.modelID
+}
+
+func (o responsesLanguageModel) Provider() string {
+ return o.provider
+}
+
+type responsesModelConfig struct {
+ isReasoningModel bool
+ systemMessageMode string
+ requiredAutoTruncation bool
+ supportsFlexProcessing bool
+ supportsPriorityProcessing bool
+}
+
+func getResponsesModelConfig(modelID string) responsesModelConfig {
+ supportsFlexProcessing := strings.HasPrefix(modelID, "o3") ||
+ strings.Contains(modelID, "-o3") || strings.Contains(modelID, "o4-mini") ||
+ (strings.Contains(modelID, "gpt-5") && !strings.Contains(modelID, "gpt-5-chat"))
+
+ supportsPriorityProcessing := strings.Contains(modelID, "gpt-4") ||
+ strings.Contains(modelID, "gpt-5-mini") ||
+ (strings.Contains(modelID, "gpt-5") &&
+ !strings.Contains(modelID, "gpt-5-nano") &&
+ !strings.Contains(modelID, "gpt-5-chat")) ||
+ strings.HasPrefix(modelID, "o3") ||
+ strings.Contains(modelID, "-o3") ||
+ strings.Contains(modelID, "o4-mini")
+
+ defaults := responsesModelConfig{
+ requiredAutoTruncation: false,
+ systemMessageMode: "system",
+ supportsFlexProcessing: supportsFlexProcessing,
+ supportsPriorityProcessing: supportsPriorityProcessing,
+ }
+
+ if strings.Contains(modelID, "gpt-5-chat") {
+ return responsesModelConfig{
+ isReasoningModel: false,
+ systemMessageMode: defaults.systemMessageMode,
+ requiredAutoTruncation: defaults.requiredAutoTruncation,
+ supportsFlexProcessing: defaults.supportsFlexProcessing,
+ supportsPriorityProcessing: defaults.supportsPriorityProcessing,
+ }
+ }
+
+ if strings.HasPrefix(modelID, "o1") || strings.Contains(modelID, "-o1") ||
+ strings.HasPrefix(modelID, "o3") || strings.Contains(modelID, "-o3") ||
+ strings.HasPrefix(modelID, "o4") || strings.Contains(modelID, "-o4") ||
+ strings.HasPrefix(modelID, "oss") || strings.Contains(modelID, "-oss") ||
+ strings.Contains(modelID, "gpt-5") || strings.Contains(modelID, "codex-") ||
+ strings.Contains(modelID, "computer-use") {
+ if strings.Contains(modelID, "o1-mini") || strings.Contains(modelID, "o1-preview") {
+ return responsesModelConfig{
+ isReasoningModel: true,
+ systemMessageMode: "remove",
+ requiredAutoTruncation: defaults.requiredAutoTruncation,
+ supportsFlexProcessing: defaults.supportsFlexProcessing,
+ supportsPriorityProcessing: defaults.supportsPriorityProcessing,
+ }
+ }
+
+ return responsesModelConfig{
+ isReasoningModel: true,
+ systemMessageMode: "developer",
+ requiredAutoTruncation: defaults.requiredAutoTruncation,
+ supportsFlexProcessing: defaults.supportsFlexProcessing,
+ supportsPriorityProcessing: defaults.supportsPriorityProcessing,
+ }
+ }
+
+ return responsesModelConfig{
+ isReasoningModel: false,
+ systemMessageMode: defaults.systemMessageMode,
+ requiredAutoTruncation: defaults.requiredAutoTruncation,
+ supportsFlexProcessing: defaults.supportsFlexProcessing,
+ supportsPriorityProcessing: defaults.supportsPriorityProcessing,
+ }
+}
+
+func (o responsesLanguageModel) prepareParams(call fantasy.Call) (*responses.ResponseNewParams, []fantasy.CallWarning) {
+ var warnings []fantasy.CallWarning
+ params := &responses.ResponseNewParams{
+ Store: param.NewOpt(false),
+ }
+
+ modelConfig := getResponsesModelConfig(o.modelID)
+
+ if call.TopK != nil {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "topK",
+ })
+ }
+
+ if call.PresencePenalty != nil {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "presencePenalty",
+ })
+ }
+
+ if call.FrequencyPenalty != nil {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "frequencyPenalty",
+ })
+ }
+
+ var openaiOptions *ResponsesProviderOptions
+ if opts, ok := call.ProviderOptions[Name]; ok {
+ if typedOpts, ok := opts.(*ResponsesProviderOptions); ok {
+ openaiOptions = typedOpts
+ }
+ }
+
+ input, inputWarnings := toResponsesPrompt(call.Prompt, modelConfig.systemMessageMode)
+ warnings = append(warnings, inputWarnings...)
+
+ var include []IncludeType
+
+ addInclude := func(key IncludeType) {
+ include = append(include, key)
+ }
+
+ topLogprobs := 0
+ if openaiOptions != nil && openaiOptions.Logprobs != nil {
+ switch v := openaiOptions.Logprobs.(type) {
+ case bool:
+ if v {
+ topLogprobs = topLogprobsMax
+ }
+ case float64:
+ topLogprobs = int(v)
+ case int:
+ topLogprobs = v
+ }
+ }
+
+ if topLogprobs > 0 {
+ addInclude(IncludeMessageOutputTextLogprobs)
+ }
+
+ params.Model = o.modelID
+ params.Input = responses.ResponseNewParamsInputUnion{
+ OfInputItemList: input,
+ }
+
+ if call.Temperature != nil {
+ params.Temperature = param.NewOpt(*call.Temperature)
+ }
+ if call.TopP != nil {
+ params.TopP = param.NewOpt(*call.TopP)
+ }
+ if call.MaxOutputTokens != nil {
+ params.MaxOutputTokens = param.NewOpt(*call.MaxOutputTokens)
+ }
+
+ if openaiOptions != nil {
+ if openaiOptions.MaxToolCalls != nil {
+ params.MaxToolCalls = param.NewOpt(*openaiOptions.MaxToolCalls)
+ }
+ if openaiOptions.Metadata != nil {
+ metadata := make(shared.Metadata)
+ for k, v := range openaiOptions.Metadata {
+ if str, ok := v.(string); ok {
+ metadata[k] = str
+ }
+ }
+ params.Metadata = metadata
+ }
+ if openaiOptions.ParallelToolCalls != nil {
+ params.ParallelToolCalls = param.NewOpt(*openaiOptions.ParallelToolCalls)
+ }
+ if openaiOptions.User != nil {
+ params.User = param.NewOpt(*openaiOptions.User)
+ }
+ if openaiOptions.Instructions != nil {
+ params.Instructions = param.NewOpt(*openaiOptions.Instructions)
+ }
+ if openaiOptions.ServiceTier != nil {
+ params.ServiceTier = responses.ResponseNewParamsServiceTier(*openaiOptions.ServiceTier)
+ }
+ if openaiOptions.PromptCacheKey != nil {
+ params.PromptCacheKey = param.NewOpt(*openaiOptions.PromptCacheKey)
+ }
+ if openaiOptions.SafetyIdentifier != nil {
+ params.SafetyIdentifier = param.NewOpt(*openaiOptions.SafetyIdentifier)
+ }
+ if topLogprobs > 0 {
+ params.TopLogprobs = param.NewOpt(int64(topLogprobs))
+ }
+
+ if len(openaiOptions.Include) > 0 {
+ include = append(include, openaiOptions.Include...)
+ }
+
+ if modelConfig.isReasoningModel && (openaiOptions.ReasoningEffort != nil || openaiOptions.ReasoningSummary != nil) {
+ reasoning := shared.ReasoningParam{}
+ if openaiOptions.ReasoningEffort != nil {
+ reasoning.Effort = shared.ReasoningEffort(*openaiOptions.ReasoningEffort)
+ }
+ if openaiOptions.ReasoningSummary != nil {
+ reasoning.Summary = shared.ReasoningSummary(*openaiOptions.ReasoningSummary)
+ }
+ params.Reasoning = reasoning
+ }
+ }
+
+ if modelConfig.requiredAutoTruncation {
+ params.Truncation = responses.ResponseNewParamsTruncationAuto
+ }
+
+ if len(include) > 0 {
+ includeParams := make([]responses.ResponseIncludable, len(include))
+ for i, inc := range include {
+ includeParams[i] = responses.ResponseIncludable(string(inc))
+ }
+ params.Include = includeParams
+ }
+
+ if modelConfig.isReasoningModel {
+ if call.Temperature != nil {
+ params.Temperature = param.Opt[float64]{}
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "temperature",
+ Details: "temperature is not supported for reasoning models",
+ })
+ }
+
+ if call.TopP != nil {
+ params.TopP = param.Opt[float64]{}
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "topP",
+ Details: "topP is not supported for reasoning models",
+ })
+ }
+ } else {
+ if openaiOptions != nil {
+ if openaiOptions.ReasoningEffort != nil {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "reasoningEffort",
+ Details: "reasoningEffort is not supported for non-reasoning models",
+ })
+ }
+
+ if openaiOptions.ReasoningSummary != nil {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "reasoningSummary",
+ Details: "reasoningSummary is not supported for non-reasoning models",
+ })
+ }
+ }
+ }
+
+ if openaiOptions != nil && openaiOptions.ServiceTier != nil {
+ if *openaiOptions.ServiceTier == ServiceTierFlex && !modelConfig.supportsFlexProcessing {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "serviceTier",
+ Details: "flex processing is only available for o3, o4-mini, and gpt-5 models",
+ })
+ params.ServiceTier = ""
+ }
+
+ if *openaiOptions.ServiceTier == ServiceTierPriority && !modelConfig.supportsPriorityProcessing {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedSetting,
+ Setting: "serviceTier",
+ Details: "priority processing is only available for supported models (gpt-4, gpt-5, gpt-5-mini, o3, o4-mini) and requires Enterprise access. gpt-5-nano is not supported",
+ })
+ params.ServiceTier = ""
+ }
+ }
+
+ tools, toolChoice, toolWarnings := toResponsesTools(call.Tools, call.ToolChoice, openaiOptions)
+ warnings = append(warnings, toolWarnings...)
+
+ if len(tools) > 0 {
+ params.Tools = tools
+ params.ToolChoice = toolChoice
+ }
+
+ return params, warnings
+}
+
+func toResponsesPrompt(prompt fantasy.Prompt, systemMessageMode string) (responses.ResponseInputParam, []fantasy.CallWarning) {
+ var input responses.ResponseInputParam
+ var warnings []fantasy.CallWarning
+
+ for _, msg := range prompt {
+ switch msg.Role {
+ case fantasy.MessageRoleSystem:
+ var systemText string
+ for _, c := range msg.Content {
+ if c.GetType() != fantasy.ContentTypeText {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "system prompt can only have text content",
+ })
+ continue
+ }
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "system prompt text part does not have the right type",
+ })
+ continue
+ }
+ if strings.TrimSpace(textPart.Text) != "" {
+ systemText += textPart.Text
+ }
+ }
+
+ if systemText == "" {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "system prompt has no text parts",
+ })
+ continue
+ }
+
+ switch systemMessageMode {
+ case "system":
+ input = append(input, responses.ResponseInputItemParamOfMessage(systemText, responses.EasyInputMessageRoleSystem))
+ case "developer":
+ input = append(input, responses.ResponseInputItemParamOfMessage(systemText, responses.EasyInputMessageRoleDeveloper))
+ case "remove":
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "system messages are removed for this model",
+ })
+ }
+
+ case fantasy.MessageRoleUser:
+ var contentParts responses.ResponseInputMessageContentListParam
+ for i, c := range msg.Content {
+ switch c.GetType() {
+ case fantasy.ContentTypeText:
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "user message text part does not have the right type",
+ })
+ continue
+ }
+ contentParts = append(contentParts, responses.ResponseInputContentUnionParam{
+ OfInputText: &responses.ResponseInputTextParam{
+ Type: "input_text",
+ Text: textPart.Text,
+ },
+ })
+
+ case fantasy.ContentTypeFile:
+ filePart, ok := fantasy.AsContentType[fantasy.FilePart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "user message file part does not have the right type",
+ })
+ continue
+ }
+
+ if strings.HasPrefix(filePart.MediaType, "image/") {
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ imageURL := fmt.Sprintf("data:%s;base64,%s", filePart.MediaType, base64Encoded)
+ contentParts = append(contentParts, responses.ResponseInputContentUnionParam{
+ OfInputImage: &responses.ResponseInputImageParam{
+ Type: "input_image",
+ ImageURL: param.NewOpt(imageURL),
+ },
+ })
+ } else if filePart.MediaType == "application/pdf" {
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ fileData := fmt.Sprintf("data:application/pdf;base64,%s", base64Encoded)
+ filename := filePart.Filename
+ if filename == "" {
+ filename = fmt.Sprintf("part-%d.pdf", i)
+ }
+ contentParts = append(contentParts, responses.ResponseInputContentUnionParam{
+ OfInputFile: &responses.ResponseInputFileParam{
+ Type: "input_file",
+ Filename: param.NewOpt(filename),
+ FileData: param.NewOpt(fileData),
+ },
+ })
+ } else {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: fmt.Sprintf("file part media type %s not supported", filePart.MediaType),
+ })
+ }
+ }
+ }
+
+ if !hasVisibleResponsesUserContent(contentParts) {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "dropping empty user message (contains neither user-facing content nor tool results)",
+ })
+ continue
+ }
+
+ input = append(input, responses.ResponseInputItemParamOfMessage(contentParts, responses.EasyInputMessageRoleUser))
+
+ case fantasy.MessageRoleAssistant:
+ startIdx := len(input)
+ for _, c := range msg.Content {
+ switch c.GetType() {
+ case fantasy.ContentTypeText:
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message text part does not have the right type",
+ })
+ continue
+ }
+ input = append(input, responses.ResponseInputItemParamOfMessage(textPart.Text, responses.EasyInputMessageRoleAssistant))
+
+ case fantasy.ContentTypeToolCall:
+ toolCallPart, ok := fantasy.AsContentType[fantasy.ToolCallPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message tool call part does not have the right type",
+ })
+ continue
+ }
+
+ if toolCallPart.ProviderExecuted {
+ continue
+ }
+
+ inputJSON, err := json.Marshal(toolCallPart.Input)
+ if err != nil {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: fmt.Sprintf("failed to marshal tool call input: %v", err),
+ })
+ continue
+ }
+
+ input = append(input, responses.ResponseInputItemParamOfFunctionCall(string(inputJSON), toolCallPart.ToolCallID, toolCallPart.ToolName))
+ case fantasy.ContentTypeReasoning:
+ reasoningMetadata := GetReasoningMetadata(c.Options())
+ if reasoningMetadata == nil || reasoningMetadata.ItemID == "" {
+ continue
+ }
+ if len(reasoningMetadata.Summary) == 0 && reasoningMetadata.EncryptedContent == nil {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message reasoning part does is empty",
+ })
+ continue
+ }
+ // we want to always send an empty array
+ summary := []responses.ResponseReasoningItemSummaryParam{}
+ for _, s := range reasoningMetadata.Summary {
+ summary = append(summary, responses.ResponseReasoningItemSummaryParam{
+ Type: "summary_text",
+ Text: s,
+ })
+ }
+ reasoning := &responses.ResponseReasoningItemParam{
+ ID: reasoningMetadata.ItemID,
+ Summary: summary,
+ }
+ if reasoningMetadata.EncryptedContent != nil {
+ reasoning.EncryptedContent = param.NewOpt(*reasoningMetadata.EncryptedContent)
+ }
+ input = append(input, responses.ResponseInputItemUnionParam{
+ OfReasoning: reasoning,
+ })
+ }
+ }
+
+ if !hasVisibleResponsesAssistantContent(input, startIdx) {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "dropping empty assistant message (contains neither user-facing content nor tool calls)",
+ })
+ // Remove any items that were added during this iteration
+ input = input[:startIdx]
+ continue
+ }
+
+ case fantasy.MessageRoleTool:
+ for _, c := range msg.Content {
+ if c.GetType() != fantasy.ContentTypeToolResult {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool message can only have tool result content",
+ })
+ continue
+ }
+
+ toolResultPart, ok := fantasy.AsContentType[fantasy.ToolResultPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool message result part does not have the right type",
+ })
+ continue
+ }
+
+ var outputStr string
+ switch toolResultPart.Output.GetType() {
+ case fantasy.ToolResultContentTypeText:
+ output, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentText](toolResultPart.Output)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool result output does not have the right type",
+ })
+ continue
+ }
+ outputStr = output.Text
+ case fantasy.ToolResultContentTypeError:
+ output, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentError](toolResultPart.Output)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool result output does not have the right type",
+ })
+ continue
+ }
+ outputStr = output.Error.Error()
+ }
+
+ input = append(input, responses.ResponseInputItemParamOfFunctionCallOutput(toolResultPart.ToolCallID, outputStr))
+ }
+ }
+ }
+
+ return input, warnings
+}
+
+func hasVisibleResponsesUserContent(content responses.ResponseInputMessageContentListParam) bool {
+ return len(content) > 0
+}
+
+func hasVisibleResponsesAssistantContent(items []responses.ResponseInputItemUnionParam, startIdx int) bool {
+ // Check if we added any assistant content parts from this message
+ for i := startIdx; i < len(items); i++ {
+ if items[i].OfMessage != nil || items[i].OfFunctionCall != nil {
+ return true
+ }
+ }
+ return false
+}
+
+func toResponsesTools(tools []fantasy.Tool, toolChoice *fantasy.ToolChoice, options *ResponsesProviderOptions) ([]responses.ToolUnionParam, responses.ResponseNewParamsToolChoiceUnion, []fantasy.CallWarning) {
+ warnings := make([]fantasy.CallWarning, 0)
+ var openaiTools []responses.ToolUnionParam
+
+ if len(tools) == 0 {
+ return nil, responses.ResponseNewParamsToolChoiceUnion{}, nil
+ }
+
+ strictJSONSchema := false
+ if options != nil && options.StrictJSONSchema != nil {
+ strictJSONSchema = *options.StrictJSONSchema
+ }
+
+ for _, tool := range tools {
+ if tool.GetType() == fantasy.ToolTypeFunction {
+ ft, ok := tool.(fantasy.FunctionTool)
+ if !ok {
+ continue
+ }
+ openaiTools = append(openaiTools, responses.ToolUnionParam{
+ OfFunction: &responses.FunctionToolParam{
+ Name: ft.Name,
+ Description: param.NewOpt(ft.Description),
+ Parameters: ft.InputSchema,
+ Strict: param.NewOpt(strictJSONSchema),
+ Type: "function",
+ },
+ })
+ continue
+ }
+
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeUnsupportedTool,
+ Tool: tool,
+ Message: "tool is not supported",
+ })
+ }
+
+ if toolChoice == nil {
+ return openaiTools, responses.ResponseNewParamsToolChoiceUnion{}, warnings
+ }
+
+ var openaiToolChoice responses.ResponseNewParamsToolChoiceUnion
+
+ switch *toolChoice {
+ case fantasy.ToolChoiceAuto:
+ openaiToolChoice = responses.ResponseNewParamsToolChoiceUnion{
+ OfToolChoiceMode: param.NewOpt(responses.ToolChoiceOptionsAuto),
+ }
+ case fantasy.ToolChoiceNone:
+ openaiToolChoice = responses.ResponseNewParamsToolChoiceUnion{
+ OfToolChoiceMode: param.NewOpt(responses.ToolChoiceOptionsNone),
+ }
+ case fantasy.ToolChoiceRequired:
+ openaiToolChoice = responses.ResponseNewParamsToolChoiceUnion{
+ OfToolChoiceMode: param.NewOpt(responses.ToolChoiceOptionsRequired),
+ }
+ default:
+ openaiToolChoice = responses.ResponseNewParamsToolChoiceUnion{
+ OfFunctionTool: &responses.ToolChoiceFunctionParam{
+ Type: "function",
+ Name: string(*toolChoice),
+ },
+ }
+ }
+
+ return openaiTools, openaiToolChoice, warnings
+}
+
+func (o responsesLanguageModel) Generate(ctx context.Context, call fantasy.Call) (*fantasy.Response, error) {
+ params, warnings := o.prepareParams(call)
+ response, err := o.client.Responses.New(ctx, *params)
+ if err != nil {
+ return nil, toProviderErr(err)
+ }
+
+ if response.Error.Message != "" {
+ return nil, &fantasy.Error{
+ Title: "provider error",
+ Message: fmt.Sprintf("%s (code: %s)", response.Error.Message, response.Error.Code),
+ }
+ }
+
+ var content []fantasy.Content
+ hasFunctionCall := false
+
+ for _, outputItem := range response.Output {
+ switch outputItem.Type {
+ case "message":
+ for _, contentPart := range outputItem.Content {
+ if contentPart.Type == "output_text" {
+ content = append(content, fantasy.TextContent{
+ Text: contentPart.Text,
+ })
+
+ for _, annotation := range contentPart.Annotations {
+ switch annotation.Type {
+ case "url_citation":
+ content = append(content, fantasy.SourceContent{
+ SourceType: fantasy.SourceTypeURL,
+ ID: uuid.NewString(),
+ URL: annotation.URL,
+ Title: annotation.Title,
+ })
+ case "file_citation":
+ title := "Document"
+ if annotation.Filename != "" {
+ title = annotation.Filename
+ }
+ filename := annotation.Filename
+ if filename == "" {
+ filename = annotation.FileID
+ }
+ content = append(content, fantasy.SourceContent{
+ SourceType: fantasy.SourceTypeDocument,
+ ID: uuid.NewString(),
+ MediaType: "text/plain",
+ Title: title,
+ Filename: filename,
+ })
+ }
+ }
+ }
+ }
+
+ case "function_call":
+ hasFunctionCall = true
+ content = append(content, fantasy.ToolCallContent{
+ ProviderExecuted: false,
+ ToolCallID: outputItem.CallID,
+ ToolName: outputItem.Name,
+ Input: outputItem.Arguments,
+ })
+
+ case "reasoning":
+ metadata := &ResponsesReasoningMetadata{
+ ItemID: outputItem.ID,
+ }
+ if outputItem.EncryptedContent != "" {
+ metadata.EncryptedContent = &outputItem.EncryptedContent
+ }
+
+ if len(outputItem.Summary) == 0 && metadata.EncryptedContent == nil {
+ continue
+ }
+
+ // When there are no summary parts, add an empty reasoning part
+ summaries := outputItem.Summary
+ if len(summaries) == 0 {
+ summaries = []responses.ResponseReasoningItemSummary{{Type: "summary_text", Text: ""}}
+ }
+
+ for _, s := range summaries {
+ metadata.Summary = append(metadata.Summary, s.Text)
+ }
+
+ content = append(content, fantasy.ReasoningContent{
+ Text: strings.Join(metadata.Summary, "\n"),
+ ProviderMetadata: fantasy.ProviderMetadata{
+ Name: metadata,
+ },
+ })
+ }
+ }
+
+ usage := fantasy.Usage{
+ InputTokens: response.Usage.InputTokens,
+ OutputTokens: response.Usage.OutputTokens,
+ TotalTokens: response.Usage.InputTokens + response.Usage.OutputTokens,
+ }
+
+ if response.Usage.OutputTokensDetails.ReasoningTokens != 0 {
+ usage.ReasoningTokens = response.Usage.OutputTokensDetails.ReasoningTokens
+ }
+ if response.Usage.InputTokensDetails.CachedTokens != 0 {
+ usage.CacheReadTokens = response.Usage.InputTokensDetails.CachedTokens
+ }
+
+ finishReason := mapResponsesFinishReason(response.IncompleteDetails.Reason, hasFunctionCall)
+
+ return &fantasy.Response{
+ Content: content,
+ Usage: usage,
+ FinishReason: finishReason,
+ ProviderMetadata: fantasy.ProviderMetadata{},
+ Warnings: warnings,
+ }, nil
+}
+
+func mapResponsesFinishReason(reason string, hasFunctionCall bool) fantasy.FinishReason {
+ if hasFunctionCall {
+ return fantasy.FinishReasonToolCalls
+ }
+
+ switch reason {
+ case "":
+ return fantasy.FinishReasonStop
+ case "max_tokens", "max_output_tokens":
+ return fantasy.FinishReasonLength
+ case "content_filter":
+ return fantasy.FinishReasonContentFilter
+ default:
+ return fantasy.FinishReasonOther
+ }
+}
+
+func (o responsesLanguageModel) Stream(ctx context.Context, call fantasy.Call) (fantasy.StreamResponse, error) {
+ params, warnings := o.prepareParams(call)
+
+ stream := o.client.Responses.NewStreaming(ctx, *params)
+
+ finishReason := fantasy.FinishReasonUnknown
+ var usage fantasy.Usage
+ ongoingToolCalls := make(map[int64]*ongoingToolCall)
+ hasFunctionCall := false
+ activeReasoning := make(map[string]*reasoningState)
+
+ return func(yield func(fantasy.StreamPart) bool) {
+ if len(warnings) > 0 {
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeWarnings,
+ Warnings: warnings,
+ }) {
+ return
+ }
+ }
+
+ for stream.Next() {
+ event := stream.Current()
+
+ switch event.Type {
+ case "response.created":
+ _ = event.AsResponseCreated()
+
+ case "response.output_item.added":
+ added := event.AsResponseOutputItemAdded()
+ switch added.Item.Type {
+ case "function_call":
+ ongoingToolCalls[added.OutputIndex] = &ongoingToolCall{
+ toolName: added.Item.Name,
+ toolCallID: added.Item.CallID,
+ }
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolInputStart,
+ ID: added.Item.CallID,
+ ToolCallName: added.Item.Name,
+ }) {
+ return
+ }
+
+ case "message":
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeTextStart,
+ ID: added.Item.ID,
+ }) {
+ return
+ }
+
+ case "reasoning":
+ metadata := &ResponsesReasoningMetadata{
+ ItemID: added.Item.ID,
+ Summary: []string{},
+ }
+ if added.Item.EncryptedContent != "" {
+ metadata.EncryptedContent = &added.Item.EncryptedContent
+ }
+
+ activeReasoning[added.Item.ID] = &reasoningState{
+ metadata: metadata,
+ }
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningStart,
+ ID: added.Item.ID,
+ ProviderMetadata: fantasy.ProviderMetadata{
+ Name: metadata,
+ },
+ }) {
+ return
+ }
+ }
+
+ case "response.output_item.done":
+ done := event.AsResponseOutputItemDone()
+ switch done.Item.Type {
+ case "function_call":
+ tc := ongoingToolCalls[done.OutputIndex]
+ if tc != nil {
+ delete(ongoingToolCalls, done.OutputIndex)
+ hasFunctionCall = true
+
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolInputEnd,
+ ID: done.Item.CallID,
+ }) {
+ return
+ }
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolCall,
+ ID: done.Item.CallID,
+ ToolCallName: done.Item.Name,
+ ToolCallInput: done.Item.Arguments,
+ }) {
+ return
+ }
+ }
+
+ case "message":
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeTextEnd,
+ ID: done.Item.ID,
+ }) {
+ return
+ }
+
+ case "reasoning":
+ state := activeReasoning[done.Item.ID]
+ if state != nil {
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: done.Item.ID,
+ ProviderMetadata: fantasy.ProviderMetadata{
+ Name: state.metadata,
+ },
+ }) {
+ return
+ }
+ delete(activeReasoning, done.Item.ID)
+ }
+ }
+
+ case "response.function_call_arguments.delta":
+ delta := event.AsResponseFunctionCallArgumentsDelta()
+ tc := ongoingToolCalls[delta.OutputIndex]
+ if tc != nil {
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeToolInputDelta,
+ ID: tc.toolCallID,
+ Delta: delta.Delta,
+ }) {
+ return
+ }
+ }
+
+ case "response.output_text.delta":
+ textDelta := event.AsResponseOutputTextDelta()
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeTextDelta,
+ ID: textDelta.ItemID,
+ Delta: textDelta.Delta,
+ }) {
+ return
+ }
+
+ case "response.reasoning_summary_part.added":
+ added := event.AsResponseReasoningSummaryPartAdded()
+ state := activeReasoning[added.ItemID]
+ if state != nil {
+ state.metadata.Summary = append(state.metadata.Summary, "")
+ activeReasoning[added.ItemID] = state
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: added.ItemID,
+ Delta: "\n",
+ ProviderMetadata: fantasy.ProviderMetadata{
+ Name: state.metadata,
+ },
+ }) {
+ return
+ }
+ }
+
+ case "response.reasoning_summary_text.delta":
+ textDelta := event.AsResponseReasoningSummaryTextDelta()
+ state := activeReasoning[textDelta.ItemID]
+ if state != nil {
+ if len(state.metadata.Summary)-1 >= int(textDelta.SummaryIndex) {
+ state.metadata.Summary[textDelta.SummaryIndex] += textDelta.Delta
+ }
+ activeReasoning[textDelta.ItemID] = state
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: textDelta.ItemID,
+ Delta: textDelta.Delta,
+ ProviderMetadata: fantasy.ProviderMetadata{
+ Name: state.metadata,
+ },
+ }) {
+ return
+ }
+ }
+
+ case "response.completed", "response.incomplete":
+ completed := event.AsResponseCompleted()
+ finishReason = mapResponsesFinishReason(completed.Response.IncompleteDetails.Reason, hasFunctionCall)
+ usage = fantasy.Usage{
+ InputTokens: completed.Response.Usage.InputTokens,
+ OutputTokens: completed.Response.Usage.OutputTokens,
+ TotalTokens: completed.Response.Usage.InputTokens + completed.Response.Usage.OutputTokens,
+ }
+ if completed.Response.Usage.OutputTokensDetails.ReasoningTokens != 0 {
+ usage.ReasoningTokens = completed.Response.Usage.OutputTokensDetails.ReasoningTokens
+ }
+ if completed.Response.Usage.InputTokensDetails.CachedTokens != 0 {
+ usage.CacheReadTokens = completed.Response.Usage.InputTokensDetails.CachedTokens
+ }
+
+ case "error":
+ errorEvent := event.AsError()
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeError,
+ Error: fmt.Errorf("response error: %s (code: %s)", errorEvent.Message, errorEvent.Code),
+ }) {
+ return
+ }
+ return
+ }
+ }
+
+ err := stream.Err()
+ if err != nil {
+ yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeError,
+ Error: toProviderErr(err),
+ })
+ return
+ }
+
+ yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeFinish,
+ Usage: usage,
+ FinishReason: finishReason,
+ })
+ }, nil
+}
+
+// GetReasoningMetadata extracts reasoning metadata from provider options for responses models.
+func GetReasoningMetadata(providerOptions fantasy.ProviderOptions) *ResponsesReasoningMetadata {
+ if openaiResponsesOptions, ok := providerOptions[Name]; ok {
+ if reasoning, ok := openaiResponsesOptions.(*ResponsesReasoningMetadata); ok {
+ return reasoning
+ }
+ }
+ return nil
+}
+
+type ongoingToolCall struct {
+ toolName string
+ toolCallID string
+}
+
+type reasoningState struct {
+ metadata *ResponsesReasoningMetadata
+}
+
+// GenerateObject implements fantasy.LanguageModel.
+func (o responsesLanguageModel) GenerateObject(ctx context.Context, call fantasy.ObjectCall) (*fantasy.ObjectResponse, error) {
+ switch o.objectMode {
+ case fantasy.ObjectModeText:
+ return object.GenerateWithText(ctx, o, call)
+ case fantasy.ObjectModeTool:
+ return object.GenerateWithTool(ctx, o, call)
+ default:
+ return o.generateObjectWithJSONMode(ctx, call)
+ }
+}
+
+// StreamObject implements fantasy.LanguageModel.
+func (o responsesLanguageModel) StreamObject(ctx context.Context, call fantasy.ObjectCall) (fantasy.ObjectStreamResponse, error) {
+ switch o.objectMode {
+ case fantasy.ObjectModeTool:
+ return object.StreamWithTool(ctx, o, call)
+ case fantasy.ObjectModeText:
+ return object.StreamWithText(ctx, o, call)
+ default:
+ return o.streamObjectWithJSONMode(ctx, call)
+ }
+}
+
+func (o responsesLanguageModel) generateObjectWithJSONMode(ctx context.Context, call fantasy.ObjectCall) (*fantasy.ObjectResponse, error) {
+ // Convert our Schema to OpenAI's JSON Schema format
+ jsonSchemaMap := schema.ToMap(call.Schema)
+
+ // Add additionalProperties: false recursively for strict mode (OpenAI requirement)
+ addAdditionalPropertiesFalse(jsonSchemaMap)
+
+ schemaName := call.SchemaName
+ if schemaName == "" {
+ schemaName = "response"
+ }
+
+ // Build request using prepareParams
+ fantasyCall := fantasy.Call{
+ Prompt: call.Prompt,
+ MaxOutputTokens: call.MaxOutputTokens,
+ Temperature: call.Temperature,
+ TopP: call.TopP,
+ PresencePenalty: call.PresencePenalty,
+ FrequencyPenalty: call.FrequencyPenalty,
+ ProviderOptions: call.ProviderOptions,
+ }
+
+ params, warnings := o.prepareParams(fantasyCall)
+
+ // Add structured output via Text.Format field
+ params.Text = responses.ResponseTextConfigParam{
+ Format: responses.ResponseFormatTextConfigParamOfJSONSchema(schemaName, jsonSchemaMap),
+ }
+
+ // Make request
+ response, err := o.client.Responses.New(ctx, *params)
+ if err != nil {
+ return nil, toProviderErr(err)
+ }
+
+ if response.Error.Message != "" {
+ return nil, &fantasy.Error{
+ Title: "provider error",
+ Message: fmt.Sprintf("%s (code: %s)", response.Error.Message, response.Error.Code),
+ }
+ }
+
+ // Extract JSON text from response
+ var jsonText string
+ for _, outputItem := range response.Output {
+ if outputItem.Type == "message" {
+ for _, contentPart := range outputItem.Content {
+ if contentPart.Type == "output_text" {
+ jsonText = contentPart.Text
+ break
+ }
+ }
+ }
+ }
+
+ if jsonText == "" {
+ usage := fantasy.Usage{
+ InputTokens: response.Usage.InputTokens,
+ OutputTokens: response.Usage.OutputTokens,
+ TotalTokens: response.Usage.InputTokens + response.Usage.OutputTokens,
+ }
+ finishReason := mapResponsesFinishReason(response.IncompleteDetails.Reason, false)
+ return nil, &fantasy.NoObjectGeneratedError{
+ RawText: "",
+ ParseError: fmt.Errorf("no text content in response"),
+ Usage: usage,
+ FinishReason: finishReason,
+ }
+ }
+
+ // Parse and validate
+ var obj any
+ if call.RepairText != nil {
+ obj, err = schema.ParseAndValidateWithRepair(ctx, jsonText, call.Schema, call.RepairText)
+ } else {
+ obj, err = schema.ParseAndValidate(jsonText, call.Schema)
+ }
+
+ usage := fantasy.Usage{
+ InputTokens: response.Usage.InputTokens,
+ OutputTokens: response.Usage.OutputTokens,
+ TotalTokens: response.Usage.InputTokens + response.Usage.OutputTokens,
+ }
+ if response.Usage.OutputTokensDetails.ReasoningTokens != 0 {
+ usage.ReasoningTokens = response.Usage.OutputTokensDetails.ReasoningTokens
+ }
+ if response.Usage.InputTokensDetails.CachedTokens != 0 {
+ usage.CacheReadTokens = response.Usage.InputTokensDetails.CachedTokens
+ }
+
+ finishReason := mapResponsesFinishReason(response.IncompleteDetails.Reason, false)
+
+ if err != nil {
+ // Add usage info to error
+ if nogErr, ok := err.(*fantasy.NoObjectGeneratedError); ok {
+ nogErr.Usage = usage
+ nogErr.FinishReason = finishReason
+ }
+ return nil, err
+ }
+
+ return &fantasy.ObjectResponse{
+ Object: obj,
+ RawText: jsonText,
+ Usage: usage,
+ FinishReason: finishReason,
+ Warnings: warnings,
+ }, nil
+}
+
+func (o responsesLanguageModel) streamObjectWithJSONMode(ctx context.Context, call fantasy.ObjectCall) (fantasy.ObjectStreamResponse, error) {
+ // Convert our Schema to OpenAI's JSON Schema format
+ jsonSchemaMap := schema.ToMap(call.Schema)
+
+ // Add additionalProperties: false recursively for strict mode (OpenAI requirement)
+ addAdditionalPropertiesFalse(jsonSchemaMap)
+
+ schemaName := call.SchemaName
+ if schemaName == "" {
+ schemaName = "response"
+ }
+
+ // Build request using prepareParams
+ fantasyCall := fantasy.Call{
+ Prompt: call.Prompt,
+ MaxOutputTokens: call.MaxOutputTokens,
+ Temperature: call.Temperature,
+ TopP: call.TopP,
+ PresencePenalty: call.PresencePenalty,
+ FrequencyPenalty: call.FrequencyPenalty,
+ ProviderOptions: call.ProviderOptions,
+ }
+
+ params, warnings := o.prepareParams(fantasyCall)
+
+ // Add structured output via Text.Format field
+ params.Text = responses.ResponseTextConfigParam{
+ Format: responses.ResponseFormatTextConfigParamOfJSONSchema(schemaName, jsonSchemaMap),
+ }
+
+ stream := o.client.Responses.NewStreaming(ctx, *params)
+
+ return func(yield func(fantasy.ObjectStreamPart) bool) {
+ if len(warnings) > 0 {
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeObject,
+ Warnings: warnings,
+ }) {
+ return
+ }
+ }
+
+ var accumulated string
+ var lastParsedObject any
+ var usage fantasy.Usage
+ var finishReason fantasy.FinishReason
+ var streamErr error
+ hasFunctionCall := false
+
+ for stream.Next() {
+ event := stream.Current()
+
+ switch event.Type {
+ case "response.output_text.delta":
+ textDelta := event.AsResponseOutputTextDelta()
+ accumulated += textDelta.Delta
+
+ // Try to parse the accumulated text
+ obj, state, parseErr := schema.ParsePartialJSON(accumulated)
+
+ // If we successfully parsed, validate and emit
+ if state == schema.ParseStateSuccessful || state == schema.ParseStateRepaired {
+ if err := schema.ValidateAgainstSchema(obj, call.Schema); err == nil {
+ // Only emit if object is different from last
+ if !reflect.DeepEqual(obj, lastParsedObject) {
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeObject,
+ Object: obj,
+ }) {
+ return
+ }
+ lastParsedObject = obj
+ }
+ }
+ }
+
+ // If parsing failed and we have a repair function, try it
+ if state == schema.ParseStateFailed && call.RepairText != nil {
+ repairedText, repairErr := call.RepairText(ctx, accumulated, parseErr)
+ if repairErr == nil {
+ obj2, state2, _ := schema.ParsePartialJSON(repairedText)
+ if (state2 == schema.ParseStateSuccessful || state2 == schema.ParseStateRepaired) &&
+ schema.ValidateAgainstSchema(obj2, call.Schema) == nil {
+ if !reflect.DeepEqual(obj2, lastParsedObject) {
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeObject,
+ Object: obj2,
+ }) {
+ return
+ }
+ lastParsedObject = obj2
+ }
+ }
+ }
+ }
+
+ case "response.completed", "response.incomplete":
+ completed := event.AsResponseCompleted()
+ finishReason = mapResponsesFinishReason(completed.Response.IncompleteDetails.Reason, hasFunctionCall)
+ usage = fantasy.Usage{
+ InputTokens: completed.Response.Usage.InputTokens,
+ OutputTokens: completed.Response.Usage.OutputTokens,
+ TotalTokens: completed.Response.Usage.InputTokens + completed.Response.Usage.OutputTokens,
+ }
+ if completed.Response.Usage.OutputTokensDetails.ReasoningTokens != 0 {
+ usage.ReasoningTokens = completed.Response.Usage.OutputTokensDetails.ReasoningTokens
+ }
+ if completed.Response.Usage.InputTokensDetails.CachedTokens != 0 {
+ usage.CacheReadTokens = completed.Response.Usage.InputTokensDetails.CachedTokens
+ }
+
+ case "error":
+ errorEvent := event.AsError()
+ streamErr = fmt.Errorf("response error: %s (code: %s)", errorEvent.Message, errorEvent.Code)
+ if !yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeError,
+ Error: streamErr,
+ }) {
+ return
+ }
+ return
+ }
+ }
+
+ err := stream.Err()
+ if err != nil {
+ yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeError,
+ Error: toProviderErr(err),
+ })
+ return
+ }
+
+ // Final validation and emit
+ if streamErr == nil && lastParsedObject != nil {
+ yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeFinish,
+ Usage: usage,
+ FinishReason: finishReason,
+ })
+ } else if streamErr == nil && lastParsedObject == nil {
+ // No object was generated
+ yield(fantasy.ObjectStreamPart{
+ Type: fantasy.ObjectStreamPartTypeError,
+ Error: &fantasy.NoObjectGeneratedError{
+ RawText: accumulated,
+ ParseError: fmt.Errorf("no valid object generated in stream"),
+ Usage: usage,
+ FinishReason: finishReason,
+ },
+ })
+ }
+ }, nil
+}
diff --git a/internal/fantasy/providers/openai/responses_options.go b/internal/fantasy/providers/openai/responses_options.go
new file mode 100644
index 000000000..7e5b1a4d0
--- /dev/null
+++ b/internal/fantasy/providers/openai/responses_options.go
@@ -0,0 +1,222 @@
+// Package openai provides an implementation of the fantasy AI SDK for OpenAI's language models.
+package openai
+
+import (
+ "encoding/json"
+ "slices"
+
+ "charm.land/fantasy"
+)
+
+// Global type identifiers for OpenAI Responses API-specific data.
+const (
+ TypeResponsesProviderOptions = Name + ".responses.options"
+ TypeResponsesReasoningMetadata = Name + ".responses.reasoning_metadata"
+)
+
+// Register OpenAI Responses API-specific types with the global registry.
+func init() {
+ fantasy.RegisterProviderType(TypeResponsesProviderOptions, func(data []byte) (fantasy.ProviderOptionsData, error) {
+ var v ResponsesProviderOptions
+ if err := json.Unmarshal(data, &v); err != nil {
+ return nil, err
+ }
+ return &v, nil
+ })
+ fantasy.RegisterProviderType(TypeResponsesReasoningMetadata, func(data []byte) (fantasy.ProviderOptionsData, error) {
+ var v ResponsesReasoningMetadata
+ if err := json.Unmarshal(data, &v); err != nil {
+ return nil, err
+ }
+ return &v, nil
+ })
+}
+
+// ResponsesReasoningMetadata represents reasoning metadata for OpenAI Responses API.
+type ResponsesReasoningMetadata struct {
+ ItemID string `json:"item_id"`
+ EncryptedContent *string `json:"encrypted_content"`
+ Summary []string `json:"summary"`
+}
+
+// Options implements the ProviderOptions interface.
+func (*ResponsesReasoningMetadata) Options() {}
+
+// MarshalJSON implements custom JSON marshaling with type info for ResponsesReasoningMetadata.
+func (m ResponsesReasoningMetadata) MarshalJSON() ([]byte, error) {
+ type plain ResponsesReasoningMetadata
+ return fantasy.MarshalProviderType(TypeResponsesReasoningMetadata, plain(m))
+}
+
+// UnmarshalJSON implements custom JSON unmarshaling with type info for ResponsesReasoningMetadata.
+func (m *ResponsesReasoningMetadata) UnmarshalJSON(data []byte) error {
+ type plain ResponsesReasoningMetadata
+ var p plain
+ if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+ return err
+ }
+ *m = ResponsesReasoningMetadata(p)
+ return nil
+}
+
+// IncludeType represents the type of content to include for OpenAI Responses API.
+type IncludeType string
+
+const (
+ // IncludeReasoningEncryptedContent includes encrypted reasoning content.
+ IncludeReasoningEncryptedContent IncludeType = "reasoning.encrypted_content"
+ // IncludeFileSearchCallResults includes file search call results.
+ IncludeFileSearchCallResults IncludeType = "file_search_call.results"
+ // IncludeMessageOutputTextLogprobs includes message output text log probabilities.
+ IncludeMessageOutputTextLogprobs IncludeType = "message.output_text.logprobs"
+)
+
+// ServiceTier represents the service tier for OpenAI Responses API.
+type ServiceTier string
+
+const (
+ // ServiceTierAuto represents the auto service tier.
+ ServiceTierAuto ServiceTier = "auto"
+ // ServiceTierFlex represents the flex service tier.
+ ServiceTierFlex ServiceTier = "flex"
+ // ServiceTierPriority represents the priority service tier.
+ ServiceTierPriority ServiceTier = "priority"
+)
+
+// TextVerbosity represents the text verbosity level for OpenAI Responses API.
+type TextVerbosity string
+
+const (
+ // TextVerbosityLow represents low text verbosity.
+ TextVerbosityLow TextVerbosity = "low"
+ // TextVerbosityMedium represents medium text verbosity.
+ TextVerbosityMedium TextVerbosity = "medium"
+ // TextVerbosityHigh represents high text verbosity.
+ TextVerbosityHigh TextVerbosity = "high"
+)
+
+// ResponsesProviderOptions represents additional options for OpenAI Responses API.
+type ResponsesProviderOptions struct {
+ Include []IncludeType `json:"include"`
+ Instructions *string `json:"instructions"`
+ Logprobs any `json:"logprobs"`
+ MaxToolCalls *int64 `json:"max_tool_calls"`
+ Metadata map[string]any `json:"metadata"`
+ ParallelToolCalls *bool `json:"parallel_tool_calls"`
+ PromptCacheKey *string `json:"prompt_cache_key"`
+ ReasoningEffort *ReasoningEffort `json:"reasoning_effort"`
+ ReasoningSummary *string `json:"reasoning_summary"`
+ SafetyIdentifier *string `json:"safety_identifier"`
+ ServiceTier *ServiceTier `json:"service_tier"`
+ StrictJSONSchema *bool `json:"strict_json_schema"`
+ TextVerbosity *TextVerbosity `json:"text_verbosity"`
+ User *string `json:"user"`
+}
+
+// Options implements the ProviderOptions interface.
+func (*ResponsesProviderOptions) Options() {}
+
+// MarshalJSON implements custom JSON marshaling with type info for ResponsesProviderOptions.
+func (o ResponsesProviderOptions) MarshalJSON() ([]byte, error) {
+ type plain ResponsesProviderOptions
+ return fantasy.MarshalProviderType(TypeResponsesProviderOptions, plain(o))
+}
+
+// UnmarshalJSON implements custom JSON unmarshaling with type info for ResponsesProviderOptions.
+func (o *ResponsesProviderOptions) UnmarshalJSON(data []byte) error {
+ type plain ResponsesProviderOptions
+ var p plain
+ if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+ return err
+ }
+ *o = ResponsesProviderOptions(p)
+ return nil
+}
+
+// responsesReasoningModelIds lists the model IDs that support reasoning for OpenAI Responses API.
+var responsesReasoningModelIDs = []string{
+ "o1",
+ "o1-2024-12-17",
+ "o3-mini",
+ "o3-mini-2025-01-31",
+ "o3",
+ "o3-2025-04-16",
+ "o4-mini",
+ "o4-mini-2025-04-16",
+ "codex-mini-latest",
+ "gpt-5",
+ "gpt-5-2025-08-07",
+ "gpt-5-mini",
+ "gpt-5-mini-2025-08-07",
+ "gpt-5-nano",
+ "gpt-5-nano-2025-08-07",
+ "gpt-5-codex",
+ "gpt-5-chat",
+ "gpt-5-pro",
+ "gpt-5.1",
+ "gpt-5.1-codex",
+ "gpt-5.1-codex-max",
+ "gpt-5.1-codex-mini",
+ "gpt-5.1-chat",
+ "gpt-5.2",
+ "gpt-5.2-codex",
+ "gpt-5.3",
+ "gpt-5.3-codex",
+ "gpt-oss-120b",
+}
+
+// responsesModelIds lists all model IDs for OpenAI Responses API.
+var responsesModelIDs = append([]string{
+ "gpt-4.1",
+ "gpt-4.1-2025-04-14",
+ "gpt-4.1-mini",
+ "gpt-4.1-mini-2025-04-14",
+ "gpt-4.1-nano",
+ "gpt-4.1-nano-2025-04-14",
+ "gpt-4o",
+ "gpt-4o-2024-05-13",
+ "gpt-4o-2024-08-06",
+ "gpt-4o-2024-11-20",
+ "gpt-4o-mini",
+ "gpt-4o-mini-2024-07-18",
+ "gpt-4-turbo",
+ "gpt-4-turbo-2024-04-09",
+ "gpt-4-turbo-preview",
+ "gpt-4-0125-preview",
+ "gpt-4-1106-preview",
+ "gpt-4",
+ "gpt-4-0613",
+ "gpt-4.5-preview",
+ "gpt-4.5-preview-2025-02-27",
+ "gpt-3.5-turbo-0125",
+ "gpt-3.5-turbo",
+ "gpt-3.5-turbo-1106",
+ "chatgpt-4o-latest",
+ "gpt-5-chat-latest",
+}, responsesReasoningModelIDs...)
+
+// NewResponsesProviderOptions creates new provider options for OpenAI Responses API.
+func NewResponsesProviderOptions(opts *ResponsesProviderOptions) fantasy.ProviderOptions {
+ return fantasy.ProviderOptions{
+ Name: opts,
+ }
+}
+
+// ParseResponsesOptions parses provider options from a map for OpenAI Responses API.
+func ParseResponsesOptions(data map[string]any) (*ResponsesProviderOptions, error) {
+ var options ResponsesProviderOptions
+ if err := fantasy.ParseOptions(data, &options); err != nil {
+ return nil, err
+ }
+ return &options, nil
+}
+
+// IsResponsesModel checks if a model ID is a Responses API model for OpenAI.
+func IsResponsesModel(modelID string) bool {
+ return slices.Contains(responsesModelIDs, modelID)
+}
+
+// IsResponsesReasoningModel checks if a model ID is a Responses API reasoning model for OpenAI.
+func IsResponsesReasoningModel(modelID string) bool {
+ return slices.Contains(responsesReasoningModelIDs, modelID)
+}
diff --git a/internal/fantasy/providers/openaicompat/language_model_hooks.go b/internal/fantasy/providers/openaicompat/language_model_hooks.go
new file mode 100644
index 000000000..0aa721d5a
--- /dev/null
+++ b/internal/fantasy/providers/openaicompat/language_model_hooks.go
@@ -0,0 +1,444 @@
+package openaicompat
+
+import (
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "strings"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/openai"
+ openaisdk "github.com/openai/openai-go/v2"
+ "github.com/openai/openai-go/v2/packages/param"
+ "github.com/openai/openai-go/v2/shared"
+)
+
+const reasoningStartedCtx = "reasoning_started"
+
+// PrepareCallFunc prepares the call for the language model.
+func PrepareCallFunc(_ fantasy.LanguageModel, params *openaisdk.ChatCompletionNewParams, call fantasy.Call) ([]fantasy.CallWarning, error) {
+ providerOptions := &ProviderOptions{}
+ if v, ok := call.ProviderOptions[Name]; ok {
+ providerOptions, ok = v.(*ProviderOptions)
+ if !ok {
+ return nil, &fantasy.Error{Title: "invalid argument", Message: "openai-compat provider options should be *openaicompat.ProviderOptions"}
+ }
+ }
+
+ if providerOptions.ReasoningEffort != nil {
+ switch *providerOptions.ReasoningEffort {
+ case openai.ReasoningEffortMinimal:
+ params.ReasoningEffort = shared.ReasoningEffortMinimal
+ case openai.ReasoningEffortLow:
+ params.ReasoningEffort = shared.ReasoningEffortLow
+ case openai.ReasoningEffortMedium:
+ params.ReasoningEffort = shared.ReasoningEffortMedium
+ case openai.ReasoningEffortHigh:
+ params.ReasoningEffort = shared.ReasoningEffortHigh
+ default:
+ return nil, fmt.Errorf("reasoning model `%s` not supported", *providerOptions.ReasoningEffort)
+ }
+ }
+
+ if providerOptions.User != nil {
+ params.User = param.NewOpt(*providerOptions.User)
+ }
+ return nil, nil
+}
+
+// ExtraContentFunc adds extra content to the response.
+func ExtraContentFunc(choice openaisdk.ChatCompletionChoice) []fantasy.Content {
+ var content []fantasy.Content
+ reasoningData := ReasoningData{}
+ err := json.Unmarshal([]byte(choice.Message.RawJSON()), &reasoningData)
+ if err != nil {
+ return content
+ }
+ if reasoningData.ReasoningContent != "" {
+ content = append(content, fantasy.ReasoningContent{
+ Text: reasoningData.ReasoningContent,
+ })
+ }
+ return content
+}
+
+func extractReasoningContext(ctx map[string]any) bool {
+ reasoningStarted, ok := ctx[reasoningStartedCtx]
+ if !ok {
+ return false
+ }
+ b, ok := reasoningStarted.(bool)
+ if !ok {
+ return false
+ }
+ return b
+}
+
+// StreamExtraFunc handles extra functionality for streaming responses.
+func StreamExtraFunc(chunk openaisdk.ChatCompletionChunk, yield func(fantasy.StreamPart) bool, ctx map[string]any) (map[string]any, bool) {
+ if len(chunk.Choices) == 0 {
+ return ctx, true
+ }
+
+ reasoningStarted := extractReasoningContext(ctx)
+
+ for inx, choice := range chunk.Choices {
+ reasoningData := ReasoningData{}
+ err := json.Unmarshal([]byte(choice.Delta.RawJSON()), &reasoningData)
+ if err != nil {
+ yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeError,
+ Error: &fantasy.Error{Title: "stream error", Message: "error unmarshalling delta", Cause: err},
+ })
+ return ctx, false
+ }
+
+ emitEvent := func(reasoningContent string) bool {
+ if !reasoningStarted {
+ shouldContinue := yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningStart,
+ ID: fmt.Sprintf("%d", inx),
+ })
+ if !shouldContinue {
+ return false
+ }
+ }
+
+ return yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: fmt.Sprintf("%d", inx),
+ Delta: reasoningContent,
+ })
+ }
+ if reasoningData.ReasoningContent != "" {
+ if !reasoningStarted {
+ ctx[reasoningStartedCtx] = true
+ }
+ return ctx, emitEvent(reasoningData.ReasoningContent)
+ }
+ if reasoningStarted && (choice.Delta.Content != "" || len(choice.Delta.ToolCalls) > 0) {
+ ctx[reasoningStartedCtx] = false
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: fmt.Sprintf("%d", inx),
+ })
+ }
+ }
+ return ctx, true
+}
+
+// ToPromptFunc converts a fantasy prompt to OpenAI format with reasoning support.
+// It handles fantasy.ContentTypeReasoning in assistant messages by adding the
+// reasoning_content field to the message JSON.
+func ToPromptFunc(prompt fantasy.Prompt, _, _ string) ([]openaisdk.ChatCompletionMessageParamUnion, []fantasy.CallWarning) {
+ var messages []openaisdk.ChatCompletionMessageParamUnion
+ var warnings []fantasy.CallWarning
+ for _, msg := range prompt {
+ switch msg.Role {
+ case fantasy.MessageRoleSystem:
+ var systemPromptParts []string
+ for _, c := range msg.Content {
+ if c.GetType() != fantasy.ContentTypeText {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "system prompt can only have text content",
+ })
+ continue
+ }
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "system prompt text part does not have the right type",
+ })
+ continue
+ }
+ text := textPart.Text
+ if strings.TrimSpace(text) != "" {
+ systemPromptParts = append(systemPromptParts, textPart.Text)
+ }
+ }
+ if len(systemPromptParts) == 0 {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "system prompt has no text parts",
+ })
+ continue
+ }
+ messages = append(messages, openaisdk.SystemMessage(strings.Join(systemPromptParts, "\n")))
+ case fantasy.MessageRoleUser:
+ // simple user message just text content
+ if len(msg.Content) == 1 && msg.Content[0].GetType() == fantasy.ContentTypeText {
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](msg.Content[0])
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "user message text part does not have the right type",
+ })
+ continue
+ }
+ messages = append(messages, openaisdk.UserMessage(textPart.Text))
+ continue
+ }
+ // text content and attachments
+ var content []openaisdk.ChatCompletionContentPartUnionParam
+ for _, c := range msg.Content {
+ switch c.GetType() {
+ case fantasy.ContentTypeText:
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "user message text part does not have the right type",
+ })
+ continue
+ }
+ content = append(content, openaisdk.ChatCompletionContentPartUnionParam{
+ OfText: &openaisdk.ChatCompletionContentPartTextParam{
+ Text: textPart.Text,
+ },
+ })
+ case fantasy.ContentTypeFile:
+ filePart, ok := fantasy.AsContentType[fantasy.FilePart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "user message file part does not have the right type",
+ })
+ continue
+ }
+
+ switch {
+ case strings.HasPrefix(filePart.MediaType, "image/"):
+ // Handle image files
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ data := "data:" + filePart.MediaType + ";base64," + base64Encoded
+ imageURL := openaisdk.ChatCompletionContentPartImageImageURLParam{URL: data}
+
+ // Check for provider-specific options like image detail
+ if providerOptions, ok := filePart.ProviderOptions[openai.Name]; ok {
+ if detail, ok := providerOptions.(*openai.ProviderFileOptions); ok {
+ imageURL.Detail = detail.ImageDetail
+ }
+ }
+
+ imageBlock := openaisdk.ChatCompletionContentPartImageParam{ImageURL: imageURL}
+ content = append(content, openaisdk.ChatCompletionContentPartUnionParam{OfImageURL: &imageBlock})
+
+ case filePart.MediaType == "audio/wav":
+ // Handle WAV audio files
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ audioBlock := openaisdk.ChatCompletionContentPartInputAudioParam{
+ InputAudio: openaisdk.ChatCompletionContentPartInputAudioInputAudioParam{
+ Data: base64Encoded,
+ Format: "wav",
+ },
+ }
+ content = append(content, openaisdk.ChatCompletionContentPartUnionParam{OfInputAudio: &audioBlock})
+
+ case filePart.MediaType == "audio/mpeg" || filePart.MediaType == "audio/mp3":
+ // Handle MP3 audio files
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ audioBlock := openaisdk.ChatCompletionContentPartInputAudioParam{
+ InputAudio: openaisdk.ChatCompletionContentPartInputAudioInputAudioParam{
+ Data: base64Encoded,
+ Format: "mp3",
+ },
+ }
+ content = append(content, openaisdk.ChatCompletionContentPartUnionParam{OfInputAudio: &audioBlock})
+
+ case filePart.MediaType == "application/pdf":
+ // Handle PDF files
+ dataStr := string(filePart.Data)
+
+ // Check if data looks like a file ID (starts with "file-")
+ if strings.HasPrefix(dataStr, "file-") {
+ fileBlock := openaisdk.ChatCompletionContentPartFileParam{
+ File: openaisdk.ChatCompletionContentPartFileFileParam{
+ FileID: param.NewOpt(dataStr),
+ },
+ }
+ content = append(content, openaisdk.ChatCompletionContentPartUnionParam{OfFile: &fileBlock})
+ } else {
+ // Handle as base64 data
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ data := "data:application/pdf;base64," + base64Encoded
+
+ filename := filePart.Filename
+ if filename == "" {
+ // Generate default filename based on content index
+ filename = fmt.Sprintf("part-%d.pdf", len(content))
+ }
+
+ fileBlock := openaisdk.ChatCompletionContentPartFileParam{
+ File: openaisdk.ChatCompletionContentPartFileFileParam{
+ Filename: param.NewOpt(filename),
+ FileData: param.NewOpt(data),
+ },
+ }
+ content = append(content, openaisdk.ChatCompletionContentPartUnionParam{OfFile: &fileBlock})
+ }
+
+ default:
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: fmt.Sprintf("file part media type %s not supported", filePart.MediaType),
+ })
+ }
+ }
+ }
+ if !hasVisibleCompatUserContent(content) {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "dropping empty user message (contains neither user-facing content nor tool results)",
+ })
+ continue
+ }
+ messages = append(messages, openaisdk.UserMessage(content))
+ case fantasy.MessageRoleAssistant:
+ // simple assistant message just text content
+ if len(msg.Content) == 1 && msg.Content[0].GetType() == fantasy.ContentTypeText {
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](msg.Content[0])
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message text part does not have the right type",
+ })
+ continue
+ }
+ messages = append(messages, openaisdk.AssistantMessage(textPart.Text))
+ continue
+ }
+ assistantMsg := openaisdk.ChatCompletionAssistantMessageParam{
+ Role: "assistant",
+ }
+ var reasoningText string
+ for _, c := range msg.Content {
+ switch c.GetType() {
+ case fantasy.ContentTypeText:
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message text part does not have the right type",
+ })
+ continue
+ }
+ assistantMsg.Content = openaisdk.ChatCompletionAssistantMessageParamContentUnion{
+ OfString: param.NewOpt(textPart.Text),
+ }
+ case fantasy.ContentTypeReasoning:
+ reasoningPart, ok := fantasy.AsContentType[fantasy.ReasoningPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message reasoning part does not have the right type",
+ })
+ continue
+ }
+ reasoningText = reasoningPart.Text
+ case fantasy.ContentTypeToolCall:
+ toolCallPart, ok := fantasy.AsContentType[fantasy.ToolCallPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message tool part does not have the right type",
+ })
+ continue
+ }
+ assistantMsg.ToolCalls = append(assistantMsg.ToolCalls,
+ openaisdk.ChatCompletionMessageToolCallUnionParam{
+ OfFunction: &openaisdk.ChatCompletionMessageFunctionToolCallParam{
+ ID: toolCallPart.ToolCallID,
+ Type: "function",
+ Function: openaisdk.ChatCompletionMessageFunctionToolCallFunctionParam{
+ Name: toolCallPart.ToolName,
+ Arguments: toolCallPart.Input,
+ },
+ },
+ })
+ }
+ }
+ // Add reasoning_content field if present
+ if reasoningText != "" {
+ assistantMsg.SetExtraFields(map[string]any{
+ "reasoning_content": reasoningText,
+ })
+ }
+ if !hasVisibleCompatAssistantContent(&assistantMsg) {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "dropping empty assistant message (contains neither user-facing content nor tool calls)",
+ })
+ continue
+ }
+ messages = append(messages, openaisdk.ChatCompletionMessageParamUnion{
+ OfAssistant: &assistantMsg,
+ })
+ case fantasy.MessageRoleTool:
+ for _, c := range msg.Content {
+ if c.GetType() != fantasy.ContentTypeToolResult {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool message can only have tool result content",
+ })
+ continue
+ }
+
+ toolResultPart, ok := fantasy.AsContentType[fantasy.ToolResultPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool message result part does not have the right type",
+ })
+ continue
+ }
+
+ switch toolResultPart.Output.GetType() {
+ case fantasy.ToolResultContentTypeText:
+ output, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentText](toolResultPart.Output)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool result output does not have the right type",
+ })
+ continue
+ }
+ messages = append(messages, openaisdk.ToolMessage(output.Text, toolResultPart.ToolCallID))
+ case fantasy.ToolResultContentTypeError:
+ output, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentError](toolResultPart.Output)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool result output does not have the right type",
+ })
+ continue
+ }
+ messages = append(messages, openaisdk.ToolMessage(output.Error.Error(), toolResultPart.ToolCallID))
+ }
+ }
+ }
+ }
+ return messages, warnings
+}
+
+func hasVisibleCompatUserContent(content []openaisdk.ChatCompletionContentPartUnionParam) bool {
+ for _, part := range content {
+ if part.OfText != nil || part.OfImageURL != nil || part.OfInputAudio != nil || part.OfFile != nil {
+ return true
+ }
+ }
+ return false
+}
+
+func hasVisibleCompatAssistantContent(msg *openaisdk.ChatCompletionAssistantMessageParam) bool {
+ // Check if there's text content
+ if !param.IsOmitted(msg.Content.OfString) || len(msg.Content.OfArrayOfContentParts) > 0 {
+ return true
+ }
+ // Check if there are tool calls
+ if len(msg.ToolCalls) > 0 {
+ return true
+ }
+ return false
+}
diff --git a/internal/fantasy/providers/openaicompat/openaicompat.go b/internal/fantasy/providers/openaicompat/openaicompat.go
new file mode 100644
index 000000000..3595a6e42
--- /dev/null
+++ b/internal/fantasy/providers/openaicompat/openaicompat.go
@@ -0,0 +1,116 @@
+// Package openaicompat provides an implementation of the fantasy AI SDK for OpenAI-compatible APIs.
+package openaicompat
+
+import (
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/openai"
+ "github.com/openai/openai-go/v2/option"
+)
+
+type options struct {
+ openaiOptions []openai.Option
+ languageModelOptions []openai.LanguageModelOption
+ sdkOptions []option.RequestOption
+ objectMode fantasy.ObjectMode
+}
+
+const (
+ // Name is the name of the OpenAI-compatible provider.
+ Name = "openai-compat"
+)
+
+// Option defines a function that configures OpenAI-compatible provider options.
+type Option = func(*options)
+
+// New creates a new OpenAI-compatible provider with the given options.
+func New(opts ...Option) (fantasy.Provider, error) {
+ providerOptions := options{
+ openaiOptions: []openai.Option{
+ openai.WithName(Name),
+ },
+ languageModelOptions: []openai.LanguageModelOption{
+ openai.WithLanguageModelPrepareCallFunc(PrepareCallFunc),
+ openai.WithLanguageModelStreamExtraFunc(StreamExtraFunc),
+ openai.WithLanguageModelExtraContentFunc(ExtraContentFunc),
+ openai.WithLanguageModelToPromptFunc(ToPromptFunc),
+ },
+ objectMode: fantasy.ObjectModeTool, // Default to tool mode for openai-compat
+ }
+ for _, o := range opts {
+ o(&providerOptions)
+ }
+
+ // Handle object mode: convert unsupported modes to tool
+ // OpenAI-compat endpoints don't support native JSON mode, so we use tool or text
+ objectMode := providerOptions.objectMode
+ if objectMode == fantasy.ObjectModeAuto || objectMode == fantasy.ObjectModeJSON {
+ objectMode = fantasy.ObjectModeTool
+ }
+
+ providerOptions.openaiOptions = append(
+ providerOptions.openaiOptions,
+ openai.WithSDKOptions(providerOptions.sdkOptions...),
+ openai.WithLanguageModelOptions(providerOptions.languageModelOptions...),
+ openai.WithObjectMode(objectMode),
+ )
+ return openai.New(providerOptions.openaiOptions...)
+}
+
+// WithBaseURL sets the base URL for the OpenAI-compatible provider.
+func WithBaseURL(url string) Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithBaseURL(url))
+ }
+}
+
+// WithAPIKey sets the API key for the OpenAI-compatible provider.
+func WithAPIKey(apiKey string) Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithAPIKey(apiKey))
+ }
+}
+
+// WithName sets the name for the OpenAI-compatible provider.
+func WithName(name string) Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithName(name))
+ }
+}
+
+// WithHeaders sets the headers for the OpenAI-compatible provider.
+func WithHeaders(headers map[string]string) Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithHeaders(headers))
+ }
+}
+
+// WithHTTPClient sets the HTTP client for the OpenAI-compatible provider.
+func WithHTTPClient(client option.HTTPClient) Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithHTTPClient(client))
+ }
+}
+
+// WithSDKOptions sets the SDK options for the OpenAI-compatible provider.
+func WithSDKOptions(opts ...option.RequestOption) Option {
+ return func(o *options) {
+ o.sdkOptions = append(o.sdkOptions, opts...)
+ }
+}
+
+// WithObjectMode sets the object generation mode for the OpenAI-compatible provider.
+// Supported modes: ObjectModeTool, ObjectModeText.
+// ObjectModeAuto and ObjectModeJSON are automatically converted to ObjectModeTool
+// since OpenAI-compatible endpoints typically don't support native JSON mode.
+func WithObjectMode(om fantasy.ObjectMode) Option {
+ return func(o *options) {
+ o.objectMode = om
+ }
+}
+
+// WithUseResponsesAPI configures the provider to use the responses API for models that support it.
+func WithUseResponsesAPI() Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithUseResponsesAPI())
+ }
+}
diff --git a/internal/fantasy/providers/openaicompat/openaicompat_test.go b/internal/fantasy/providers/openaicompat/openaicompat_test.go
new file mode 100644
index 000000000..a603e5e66
--- /dev/null
+++ b/internal/fantasy/providers/openaicompat/openaicompat_test.go
@@ -0,0 +1,434 @@
+package openaicompat
+
+import (
+ "errors"
+ "testing"
+
+ "charm.land/fantasy"
+ "github.com/stretchr/testify/require"
+)
+
+func TestToPromptFunc_ReasoningContent(t *testing.T) {
+ t.Parallel()
+
+ t.Run("should add reasoning_content field to assistant messages", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "What is 2+2?"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.ReasoningPart{Text: "Let me think... 2+2 equals 4."},
+ fantasy.TextPart{Text: "The answer is 4."},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "What about 3+3?"},
+ },
+ },
+ }
+
+ messages, warnings := ToPromptFunc(prompt, "", "")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 3)
+
+ // First message (user) - no reasoning
+ msg1 := messages[0].OfUser
+ require.NotNil(t, msg1)
+ require.Equal(t, "What is 2+2?", msg1.Content.OfString.Value)
+
+ // Second message (assistant) - with reasoning
+ msg2 := messages[1].OfAssistant
+ require.NotNil(t, msg2)
+ require.Equal(t, "The answer is 4.", msg2.Content.OfString.Value)
+ // Check reasoning_content in extra fields
+ extraFields := msg2.ExtraFields()
+ reasoningContent, hasReasoning := extraFields["reasoning_content"]
+ require.True(t, hasReasoning)
+ require.Equal(t, "Let me think... 2+2 equals 4.", reasoningContent)
+
+ // Third message (user) - no reasoning
+ msg3 := messages[2].OfUser
+ require.NotNil(t, msg3)
+ require.Equal(t, "What about 3+3?", msg3.Content.OfString.Value)
+ })
+
+ t.Run("should handle assistant messages with only reasoning content", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.ReasoningPart{Text: "Internal reasoning only..."},
+ },
+ },
+ }
+
+ messages, warnings := ToPromptFunc(prompt, "", "")
+
+ require.Len(t, warnings, 1)
+ require.Contains(t, warnings[0].Message, "dropping empty assistant message")
+ require.Len(t, messages, 1) // Only user message, assistant message dropped
+
+ // User message - unchanged
+ msg := messages[0].OfUser
+ require.NotNil(t, msg)
+ require.Equal(t, "Hello", msg.Content.OfString.Value)
+ })
+
+ t.Run("should not add reasoning_content to messages without reasoning", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hi there!"},
+ },
+ },
+ }
+
+ messages, warnings := ToPromptFunc(prompt, "", "")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 2)
+
+ // Assistant message without reasoning
+ msg := messages[1].OfAssistant
+ require.NotNil(t, msg)
+ require.Equal(t, "Hi there!", msg.Content.OfString.Value)
+ extraFields := msg.ExtraFields()
+ _, hasReasoning := extraFields["reasoning_content"]
+ require.False(t, hasReasoning)
+ })
+
+ t.Run("should preserve system and user messages unchanged", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleSystem,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "You are helpful."},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ }
+
+ messages, warnings := ToPromptFunc(prompt, "", "")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 2)
+
+ // System message - unchanged
+ systemMsg := messages[0].OfSystem
+ require.NotNil(t, systemMsg)
+ require.Equal(t, "You are helpful.", systemMsg.Content.OfString.Value)
+
+ // User message - unchanged
+ userMsg := messages[1].OfUser
+ require.NotNil(t, userMsg)
+ require.Equal(t, "Hello", userMsg.Content.OfString.Value)
+ })
+
+ t.Run("should use last assistant TextPart only", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "First part. "},
+ fantasy.TextPart{Text: "Second part. "},
+ fantasy.TextPart{Text: "Third part."},
+ },
+ },
+ }
+
+ messages, warnings := ToPromptFunc(prompt, "", "")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 2)
+
+ // Assistant message should use only the last TextPart (matching openai behavior)
+ assistantMsg := messages[1].OfAssistant
+ require.NotNil(t, assistantMsg)
+ require.Equal(t, "Third part.", assistantMsg.Content.OfString.Value)
+ })
+
+ t.Run("should include user messages with only unsupported attachments", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ MediaType: "application/x-unsupported",
+ Data: []byte("unsupported data"),
+ },
+ },
+ },
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "After unsupported"},
+ },
+ },
+ }
+
+ messages, warnings := ToPromptFunc(prompt, "", "")
+
+ require.Len(t, warnings, 2) // unsupported type + empty message
+ require.Contains(t, warnings[0].Message, "not supported")
+ require.Contains(t, warnings[1].Message, "dropping empty user message")
+ // Should have only 2 messages (empty content message is now dropped)
+ require.Len(t, messages, 2)
+
+ msg1 := messages[0].OfUser
+ require.NotNil(t, msg1)
+ require.Equal(t, "Hello", msg1.Content.OfString.Value)
+
+ msg2 := messages[1].OfUser
+ require.NotNil(t, msg2)
+ require.Equal(t, "After unsupported", msg2.Content.OfString.Value)
+ })
+
+ t.Run("should detect PDF file IDs using strings.HasPrefix", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Check this PDF"},
+ fantasy.FilePart{
+ MediaType: "application/pdf",
+ Data: []byte("file-abc123xyz"),
+ Filename: "test.pdf",
+ },
+ },
+ },
+ }
+
+ messages, warnings := ToPromptFunc(prompt, "", "")
+
+ require.Empty(t, warnings)
+ require.Len(t, messages, 1)
+
+ userMsg := messages[0].OfUser
+ require.NotNil(t, userMsg)
+
+ content := userMsg.Content.OfArrayOfContentParts
+ require.Len(t, content, 2)
+
+ // Second content part should be file with file_id
+ filePart := content[1].OfFile
+ require.NotNil(t, filePart)
+ require.Equal(t, "file-abc123xyz", filePart.File.FileID.Value)
+ })
+}
+
+func TestToPromptFunc_DropsEmptyMessages(t *testing.T) {
+ t.Parallel()
+
+ t.Run("should drop truly empty assistant messages", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{},
+ },
+ }
+
+ messages, warnings := ToPromptFunc(prompt, "", "")
+
+ require.Len(t, messages, 1, "should only have user message")
+ require.Len(t, warnings, 1)
+ require.Equal(t, fantasy.CallWarningTypeOther, warnings[0].Type)
+ require.Contains(t, warnings[0].Message, "dropping empty assistant message")
+ })
+
+ t.Run("should keep assistant messages with text content", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hello"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "Hi there!"},
+ },
+ },
+ }
+
+ messages, warnings := ToPromptFunc(prompt, "", "")
+
+ require.Len(t, messages, 2, "should have both user and assistant messages")
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should keep assistant messages with tool calls", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "What's the weather?"},
+ },
+ },
+ {
+ Role: fantasy.MessageRoleAssistant,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolCallPart{
+ ToolCallID: "call_123",
+ ToolName: "get_weather",
+ Input: `{"location":"NYC"}`,
+ },
+ },
+ },
+ }
+
+ messages, warnings := ToPromptFunc(prompt, "", "")
+
+ require.Len(t, messages, 2, "should have both user and assistant messages")
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should drop user messages without visible content", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ Data: []byte("not supported"),
+ MediaType: "application/unknown",
+ },
+ },
+ },
+ }
+
+ messages, warnings := ToPromptFunc(prompt, "", "")
+
+ require.Empty(t, messages)
+ require.Len(t, warnings, 2) // unsupported type + empty message
+ require.Contains(t, warnings[1].Message, "dropping empty user message")
+ })
+
+ t.Run("should keep user messages with image content", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.FilePart{
+ Data: []byte{0x01, 0x02, 0x03},
+ MediaType: "image/png",
+ },
+ },
+ },
+ }
+
+ messages, warnings := ToPromptFunc(prompt, "", "")
+
+ require.Len(t, messages, 1)
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should keep user messages with tool results", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleTool,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolResultPart{
+ ToolCallID: "call_123",
+ Output: fantasy.ToolResultOutputContentText{Text: "done"},
+ },
+ },
+ },
+ }
+
+ messages, warnings := ToPromptFunc(prompt, "", "")
+
+ require.Len(t, messages, 1)
+ require.Empty(t, warnings)
+ })
+
+ t.Run("should keep user messages with tool error results", func(t *testing.T) {
+ t.Parallel()
+
+ prompt := fantasy.Prompt{
+ {
+ Role: fantasy.MessageRoleTool,
+ Content: []fantasy.MessagePart{
+ fantasy.ToolResultPart{
+ ToolCallID: "call_456",
+ Output: fantasy.ToolResultOutputContentError{Error: errors.New("boom")},
+ },
+ },
+ },
+ }
+
+ messages, warnings := ToPromptFunc(prompt, "", "")
+
+ require.Len(t, messages, 1)
+ require.Empty(t, warnings)
+ })
+}
diff --git a/internal/fantasy/providers/openaicompat/provider_options.go b/internal/fantasy/providers/openaicompat/provider_options.go
new file mode 100644
index 000000000..afb037bf2
--- /dev/null
+++ b/internal/fantasy/providers/openaicompat/provider_options.go
@@ -0,0 +1,72 @@
+// Package openaicompat provides an implementation of the fantasy AI SDK for OpenAI-compatible APIs.
+package openaicompat
+
+import (
+ "encoding/json"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/openai"
+)
+
+// Global type identifiers for OpenAI-compatible provider data.
+const (
+ TypeProviderOptions = Name + ".options"
+)
+
+// Register OpenAI-compatible provider-specific types with the global registry.
+func init() {
+ fantasy.RegisterProviderType(TypeProviderOptions, func(data []byte) (fantasy.ProviderOptionsData, error) {
+ var v ProviderOptions
+ if err := json.Unmarshal(data, &v); err != nil {
+ return nil, err
+ }
+ return &v, nil
+ })
+}
+
+// ProviderOptions represents additional options for the OpenAI-compatible provider.
+type ProviderOptions struct {
+ User *string `json:"user"`
+ ReasoningEffort *openai.ReasoningEffort `json:"reasoning_effort"`
+}
+
+// ReasoningData represents reasoning data for OpenAI-compatible provider.
+type ReasoningData struct {
+ ReasoningContent string `json:"reasoning_content"`
+}
+
+// Options implements the ProviderOptions interface.
+func (*ProviderOptions) Options() {}
+
+// MarshalJSON implements custom JSON marshaling with type info for ProviderOptions.
+func (o ProviderOptions) MarshalJSON() ([]byte, error) {
+ type plain ProviderOptions
+ return fantasy.MarshalProviderType(TypeProviderOptions, plain(o))
+}
+
+// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderOptions.
+func (o *ProviderOptions) UnmarshalJSON(data []byte) error {
+ type plain ProviderOptions
+ var p plain
+ if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+ return err
+ }
+ *o = ProviderOptions(p)
+ return nil
+}
+
+// NewProviderOptions creates new provider options for the OpenAI-compatible provider.
+func NewProviderOptions(opts *ProviderOptions) fantasy.ProviderOptions {
+ return fantasy.ProviderOptions{
+ Name: opts,
+ }
+}
+
+// ParseOptions parses provider options from a map for OpenAI-compatible provider.
+func ParseOptions(data map[string]any) (*ProviderOptions, error) {
+ var options ProviderOptions
+ if err := fantasy.ParseOptions(data, &options); err != nil {
+ return nil, err
+ }
+ return &options, nil
+}
diff --git a/internal/fantasy/providers/openrouter/language_model_hooks.go b/internal/fantasy/providers/openrouter/language_model_hooks.go
new file mode 100644
index 000000000..fb69565ac
--- /dev/null
+++ b/internal/fantasy/providers/openrouter/language_model_hooks.go
@@ -0,0 +1,1036 @@
+package openrouter
+
+import (
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "maps"
+ "strings"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/anthropic"
+ "charm.land/fantasy/providers/google"
+ "charm.land/fantasy/providers/openai"
+ openaisdk "github.com/openai/openai-go/v2"
+ "github.com/openai/openai-go/v2/packages/param"
+)
+
+const reasoningStartedCtx = "reasoning_started"
+
+func languagePrepareModelCall(_ fantasy.LanguageModel, params *openaisdk.ChatCompletionNewParams, call fantasy.Call) ([]fantasy.CallWarning, error) {
+ providerOptions := &ProviderOptions{}
+ if v, ok := call.ProviderOptions[Name]; ok {
+ providerOptions, ok = v.(*ProviderOptions)
+ if !ok {
+ return nil, &fantasy.Error{Title: "invalid argument", Message: "openrouter provider options should be *openrouter.ProviderOptions"}
+ }
+ }
+
+ extraFields := make(map[string]any)
+
+ if providerOptions.Provider != nil {
+ data, err := structToMapJSON(providerOptions.Provider)
+ if err != nil {
+ return nil, err
+ }
+ extraFields["provider"] = data
+ }
+
+ if providerOptions.Reasoning != nil {
+ data, err := structToMapJSON(providerOptions.Reasoning)
+ if err != nil {
+ return nil, err
+ }
+ extraFields["reasoning"] = data
+ }
+
+ if providerOptions.IncludeUsage != nil {
+ extraFields["usage"] = map[string]any{
+ "include": *providerOptions.IncludeUsage,
+ }
+ } else { // default include usage
+ extraFields["usage"] = map[string]any{
+ "include": true,
+ }
+ }
+ if providerOptions.LogitBias != nil {
+ params.LogitBias = providerOptions.LogitBias
+ }
+ if providerOptions.LogProbs != nil {
+ params.Logprobs = param.NewOpt(*providerOptions.LogProbs)
+ }
+ if providerOptions.User != nil {
+ params.User = param.NewOpt(*providerOptions.User)
+ }
+ if providerOptions.ParallelToolCalls != nil {
+ params.ParallelToolCalls = param.NewOpt(*providerOptions.ParallelToolCalls)
+ }
+
+ maps.Copy(extraFields, providerOptions.ExtraBody)
+ params.SetExtraFields(extraFields)
+ return nil, nil
+}
+
+func languageModelExtraContent(choice openaisdk.ChatCompletionChoice) []fantasy.Content {
+ content := make([]fantasy.Content, 0)
+ reasoningData := ReasoningData{}
+ err := json.Unmarshal([]byte(choice.Message.RawJSON()), &reasoningData)
+ if err != nil {
+ return content
+ }
+ type anthropicReasoningBlock struct {
+ text string
+ metadata *anthropic.ReasoningOptionMetadata
+ }
+ type googleReasoningBlock struct {
+ text string
+ metadata *google.ReasoningMetadata
+ }
+
+ responsesReasoningBlocks := make([]openai.ResponsesReasoningMetadata, 0)
+ anthropicReasoningBlocks := make([]anthropicReasoningBlock, 0)
+ googleReasoningBlocks := make([]googleReasoningBlock, 0)
+ otherReasoning := make([]string, 0)
+ for _, detail := range reasoningData.ReasoningDetails {
+ if strings.HasPrefix(detail.Format, "openai-responses") || strings.HasPrefix(detail.Format, "xai-responses") {
+ var thinkingBlock openai.ResponsesReasoningMetadata
+ if len(responsesReasoningBlocks)-1 >= detail.Index {
+ thinkingBlock = responsesReasoningBlocks[detail.Index]
+ } else {
+ thinkingBlock = openai.ResponsesReasoningMetadata{}
+ responsesReasoningBlocks = append(responsesReasoningBlocks, thinkingBlock)
+ }
+
+ switch detail.Type {
+ case "reasoning.summary":
+ thinkingBlock.Summary = append(thinkingBlock.Summary, detail.Summary)
+ case "reasoning.encrypted":
+ thinkingBlock.EncryptedContent = &detail.Data
+ }
+ if detail.ID != "" {
+ thinkingBlock.ItemID = detail.ID
+ }
+
+ responsesReasoningBlocks[detail.Index] = thinkingBlock
+ continue
+ }
+ if strings.HasPrefix(detail.Format, "google-gemini") {
+ var thinkingBlock googleReasoningBlock
+ if len(googleReasoningBlocks)-1 >= detail.Index {
+ thinkingBlock = googleReasoningBlocks[detail.Index]
+ } else {
+ thinkingBlock = googleReasoningBlock{metadata: &google.ReasoningMetadata{}}
+ googleReasoningBlocks = append(googleReasoningBlocks, thinkingBlock)
+ }
+
+ switch detail.Type {
+ case "reasoning.text":
+ thinkingBlock.text = detail.Text
+ case "reasoning.encrypted":
+ thinkingBlock.metadata.Signature = detail.Data
+ thinkingBlock.metadata.ToolID = detail.ID
+ }
+
+ googleReasoningBlocks[detail.Index] = thinkingBlock
+ continue
+ }
+
+ if strings.HasPrefix(detail.Format, "anthropic-claude") {
+ anthropicReasoningBlocks = append(anthropicReasoningBlocks, anthropicReasoningBlock{
+ text: detail.Text,
+ metadata: &anthropic.ReasoningOptionMetadata{
+ Signature: detail.Signature,
+ },
+ })
+ continue
+ }
+
+ otherReasoning = append(otherReasoning, detail.Text)
+ }
+
+ for _, block := range responsesReasoningBlocks {
+ if len(block.Summary) == 0 {
+ block.Summary = []string{""}
+ }
+ content = append(content, fantasy.ReasoningContent{
+ Text: strings.Join(block.Summary, "\n"),
+ ProviderMetadata: fantasy.ProviderMetadata{
+ openai.Name: &block,
+ },
+ })
+ }
+ for _, block := range anthropicReasoningBlocks {
+ content = append(content, fantasy.ReasoningContent{
+ Text: block.text,
+ ProviderMetadata: fantasy.ProviderMetadata{
+ anthropic.Name: block.metadata,
+ },
+ })
+ }
+ for _, block := range googleReasoningBlocks {
+ content = append(content, fantasy.ReasoningContent{
+ Text: block.text,
+ ProviderMetadata: fantasy.ProviderMetadata{
+ google.Name: block.metadata,
+ },
+ })
+ }
+
+ for _, reasoning := range otherReasoning {
+ content = append(content, fantasy.ReasoningContent{
+ Text: reasoning,
+ })
+ }
+ return content
+}
+
+type currentReasoningState struct {
+ metadata *openai.ResponsesReasoningMetadata
+ googleMetadata *google.ReasoningMetadata
+ googleText string
+}
+
+func extractReasoningContext(ctx map[string]any) *currentReasoningState {
+ reasoningStarted, ok := ctx[reasoningStartedCtx]
+ if !ok {
+ return nil
+ }
+ state, ok := reasoningStarted.(*currentReasoningState)
+ if !ok {
+ return nil
+ }
+ return state
+}
+
+func languageModelStreamExtra(chunk openaisdk.ChatCompletionChunk, yield func(fantasy.StreamPart) bool, ctx map[string]any) (map[string]any, bool) {
+ if len(chunk.Choices) == 0 {
+ return ctx, true
+ }
+
+ currentState := extractReasoningContext(ctx)
+
+ inx := 0
+ choice := chunk.Choices[inx]
+ reasoningData := ReasoningData{}
+ err := json.Unmarshal([]byte(choice.Delta.RawJSON()), &reasoningData)
+ if err != nil {
+ yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeError,
+ Error: &fantasy.Error{Title: "stream error", Message: "error unmarshalling delta", Cause: err},
+ })
+ return ctx, false
+ }
+
+ // Reasoning Start
+ if currentState == nil {
+ if len(reasoningData.ReasoningDetails) == 0 {
+ return ctx, true
+ }
+
+ var metadata fantasy.ProviderMetadata
+ currentState = ¤tReasoningState{}
+
+ detail := reasoningData.ReasoningDetails[0]
+ if strings.HasPrefix(detail.Format, "openai-responses") || strings.HasPrefix(detail.Format, "xai-responses") {
+ currentState.metadata = &openai.ResponsesReasoningMetadata{
+ Summary: []string{detail.Summary},
+ }
+ metadata = fantasy.ProviderMetadata{
+ openai.Name: currentState.metadata,
+ }
+ // There was no summary just thinking we just send this as if it ended alredy
+ if detail.Data != "" {
+ shouldContinue := yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningStart,
+ ID: fmt.Sprintf("%d", inx),
+ Delta: detail.Summary,
+ ProviderMetadata: metadata,
+ })
+ if !shouldContinue {
+ return ctx, false
+ }
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: fmt.Sprintf("%d", inx),
+ ProviderMetadata: fantasy.ProviderMetadata{
+ openai.Name: &openai.ResponsesReasoningMetadata{
+ Summary: []string{detail.Summary},
+ EncryptedContent: &detail.Data,
+ ItemID: detail.ID,
+ },
+ },
+ })
+ }
+ }
+
+ if strings.HasPrefix(detail.Format, "google-gemini") {
+ // this means there is only encrypted data available start and finish right away
+ if detail.Type == "reasoning.encrypted" {
+ ctx[reasoningStartedCtx] = nil
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningStart,
+ ID: fmt.Sprintf("%d", inx),
+ }) {
+ return ctx, false
+ }
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: fmt.Sprintf("%d", inx),
+ ProviderMetadata: fantasy.ProviderMetadata{
+ google.Name: &google.ReasoningMetadata{
+ Signature: detail.Data,
+ ToolID: detail.ID,
+ },
+ },
+ })
+ }
+ currentState.googleMetadata = &google.ReasoningMetadata{}
+ currentState.googleText = detail.Text
+ metadata = fantasy.ProviderMetadata{
+ google.Name: currentState.googleMetadata,
+ }
+ }
+
+ ctx[reasoningStartedCtx] = currentState
+ delta := detail.Summary
+ if strings.HasPrefix(detail.Format, "google-gemini") {
+ delta = detail.Text
+ }
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningStart,
+ ID: fmt.Sprintf("%d", inx),
+ Delta: delta,
+ ProviderMetadata: metadata,
+ })
+ }
+ if len(reasoningData.ReasoningDetails) == 0 {
+ // this means its a model different from openai/anthropic that ended reasoning
+ if choice.Delta.Content != "" || len(choice.Delta.ToolCalls) > 0 {
+ ctx[reasoningStartedCtx] = nil
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: fmt.Sprintf("%d", inx),
+ })
+ }
+ return ctx, true
+ }
+ // Reasoning delta
+ detail := reasoningData.ReasoningDetails[0]
+ if strings.HasPrefix(detail.Format, "openai-responses") || strings.HasPrefix(detail.Format, "xai-responses") {
+ // Reasoning has ended
+ if detail.Data != "" {
+ currentState.metadata.EncryptedContent = &detail.Data
+ currentState.metadata.ItemID = detail.ID
+ ctx[reasoningStartedCtx] = nil
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: fmt.Sprintf("%d", inx),
+ ProviderMetadata: fantasy.ProviderMetadata{
+ openai.Name: currentState.metadata,
+ },
+ })
+ }
+ var textDelta string
+ // add to existing summary
+ if len(currentState.metadata.Summary)-1 >= detail.Index {
+ currentState.metadata.Summary[detail.Index] += detail.Summary
+ textDelta = detail.Summary
+ } else { // add new summary
+ currentState.metadata.Summary = append(currentState.metadata.Summary, detail.Summary)
+ textDelta = "\n" + detail.Summary
+ }
+ ctx[reasoningStartedCtx] = currentState
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: fmt.Sprintf("%d", inx),
+ Delta: textDelta,
+ ProviderMetadata: fantasy.ProviderMetadata{
+ openai.Name: currentState.metadata,
+ },
+ })
+ }
+ if strings.HasPrefix(detail.Format, "anthropic-claude") {
+ // the reasoning has ended
+ if detail.Signature != "" {
+ metadata := fantasy.ProviderMetadata{
+ anthropic.Name: &anthropic.ReasoningOptionMetadata{
+ Signature: detail.Signature,
+ },
+ }
+ // initial update
+ shouldContinue := yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: fmt.Sprintf("%d", inx),
+ Delta: detail.Text,
+ ProviderMetadata: metadata,
+ })
+ if !shouldContinue {
+ return ctx, false
+ }
+ ctx[reasoningStartedCtx] = nil
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: fmt.Sprintf("%d", inx),
+ })
+ }
+
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: fmt.Sprintf("%d", inx),
+ Delta: detail.Text,
+ })
+ }
+
+ if strings.HasPrefix(detail.Format, "google-gemini") {
+ // reasoning.text type - accumulate text
+ if detail.Type == "reasoning.text" {
+ currentState.googleText += detail.Text
+ ctx[reasoningStartedCtx] = currentState
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: fmt.Sprintf("%d", inx),
+ Delta: detail.Text,
+ })
+ }
+
+ // reasoning.encrypted type - end reasoning with signature
+ if detail.Type == "reasoning.encrypted" {
+ currentState.googleMetadata.Signature = detail.Data
+ currentState.googleMetadata.ToolID = detail.ID
+ metadata := fantasy.ProviderMetadata{
+ google.Name: currentState.googleMetadata,
+ }
+ ctx[reasoningStartedCtx] = nil
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: fmt.Sprintf("%d", inx),
+ ProviderMetadata: metadata,
+ })
+ }
+ }
+
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: fmt.Sprintf("%d", inx),
+ Delta: detail.Text,
+ })
+}
+
+func languageModelUsage(response openaisdk.ChatCompletion) (fantasy.Usage, fantasy.ProviderOptionsData) {
+ if len(response.Choices) == 0 {
+ return fantasy.Usage{}, nil
+ }
+ openrouterUsage := UsageAccounting{}
+ usage := response.Usage
+
+ _ = json.Unmarshal([]byte(usage.RawJSON()), &openrouterUsage)
+
+ completionTokenDetails := usage.CompletionTokensDetails
+ promptTokenDetails := usage.PromptTokensDetails
+
+ var provider string
+ if p, ok := response.JSON.ExtraFields["provider"]; ok {
+ provider = p.Raw()
+ }
+
+ // Build provider metadata
+ providerMetadata := &ProviderMetadata{
+ Provider: provider,
+ Usage: openrouterUsage,
+ }
+
+ return fantasy.Usage{
+ InputTokens: usage.PromptTokens,
+ OutputTokens: usage.CompletionTokens,
+ TotalTokens: usage.TotalTokens,
+ ReasoningTokens: completionTokenDetails.ReasoningTokens,
+ CacheReadTokens: promptTokenDetails.CachedTokens,
+ }, providerMetadata
+}
+
+func languageModelStreamUsage(chunk openaisdk.ChatCompletionChunk, _ map[string]any, metadata fantasy.ProviderMetadata) (fantasy.Usage, fantasy.ProviderMetadata) {
+ usage := chunk.Usage
+ if usage.TotalTokens == 0 {
+ return fantasy.Usage{}, nil
+ }
+
+ streamProviderMetadata := &ProviderMetadata{}
+ if metadata != nil {
+ if providerMetadata, ok := metadata[Name]; ok {
+ converted, ok := providerMetadata.(*ProviderMetadata)
+ if ok {
+ streamProviderMetadata = converted
+ }
+ }
+ }
+ openrouterUsage := UsageAccounting{}
+ _ = json.Unmarshal([]byte(usage.RawJSON()), &openrouterUsage)
+ streamProviderMetadata.Usage = openrouterUsage
+
+ if p, ok := chunk.JSON.ExtraFields["provider"]; ok {
+ streamProviderMetadata.Provider = p.Raw()
+ }
+
+ // we do this here because the acc does not add prompt details
+ completionTokenDetails := usage.CompletionTokensDetails
+ promptTokenDetails := usage.PromptTokensDetails
+ aiUsage := fantasy.Usage{
+ InputTokens: usage.PromptTokens,
+ OutputTokens: usage.CompletionTokens,
+ TotalTokens: usage.TotalTokens,
+ ReasoningTokens: completionTokenDetails.ReasoningTokens,
+ CacheReadTokens: promptTokenDetails.CachedTokens,
+ }
+
+ return aiUsage, fantasy.ProviderMetadata{
+ Name: streamProviderMetadata,
+ }
+}
+
+func languageModelToPrompt(prompt fantasy.Prompt, _, model string) ([]openaisdk.ChatCompletionMessageParamUnion, []fantasy.CallWarning) {
+ var messages []openaisdk.ChatCompletionMessageParamUnion
+ var warnings []fantasy.CallWarning
+ for _, msg := range prompt {
+ switch msg.Role {
+ case fantasy.MessageRoleSystem:
+ var systemPromptParts []string
+ for _, c := range msg.Content {
+ if c.GetType() != fantasy.ContentTypeText {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "system prompt can only have text content",
+ })
+ continue
+ }
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "system prompt text part does not have the right type",
+ })
+ continue
+ }
+ text := textPart.Text
+ if strings.TrimSpace(text) != "" {
+ systemPromptParts = append(systemPromptParts, textPart.Text)
+ }
+ }
+ if len(systemPromptParts) == 0 {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "system prompt has no text parts",
+ })
+ continue
+ }
+ systemMsg := openaisdk.SystemMessage(strings.Join(systemPromptParts, "\n"))
+ anthropicCache := anthropic.GetCacheControl(msg.ProviderOptions)
+ if anthropicCache != nil {
+ systemMsg.OfSystem.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": anthropicCache.Type,
+ },
+ })
+ }
+ messages = append(messages, systemMsg)
+ case fantasy.MessageRoleUser:
+ // simple user message just text content
+ if len(msg.Content) == 1 && msg.Content[0].GetType() == fantasy.ContentTypeText {
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](msg.Content[0])
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "user message text part does not have the right type",
+ })
+ continue
+ }
+ userMsg := openaisdk.UserMessage(textPart.Text)
+
+ anthropicCache := anthropic.GetCacheControl(msg.ProviderOptions)
+ if anthropicCache != nil {
+ userMsg.OfUser.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": anthropicCache.Type,
+ },
+ })
+ }
+ messages = append(messages, userMsg)
+ continue
+ }
+ // text content and attachments
+ // for now we only support image content later we need to check
+ // TODO: add the supported media types to the language model so we
+ // can use that to validate the data here.
+ var content []openaisdk.ChatCompletionContentPartUnionParam
+ for i, c := range msg.Content {
+ isLastPart := i == len(msg.Content)-1
+ cacheControl := anthropic.GetCacheControl(c.Options())
+ if cacheControl == nil && isLastPart {
+ cacheControl = anthropic.GetCacheControl(msg.ProviderOptions)
+ }
+ switch c.GetType() {
+ case fantasy.ContentTypeText:
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "user message text part does not have the right type",
+ })
+ continue
+ }
+ part := openaisdk.ChatCompletionContentPartUnionParam{
+ OfText: &openaisdk.ChatCompletionContentPartTextParam{
+ Text: textPart.Text,
+ },
+ }
+ if cacheControl != nil {
+ part.OfText.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ content = append(content, part)
+ case fantasy.ContentTypeFile:
+ filePart, ok := fantasy.AsContentType[fantasy.FilePart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "user message file part does not have the right type",
+ })
+ continue
+ }
+
+ switch {
+ case strings.HasPrefix(filePart.MediaType, "image/"):
+ // Handle image files
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ data := "data:" + filePart.MediaType + ";base64," + base64Encoded
+ imageURL := openaisdk.ChatCompletionContentPartImageImageURLParam{URL: data}
+
+ // Check for provider-specific options like image detail
+ if providerOptions, ok := filePart.ProviderOptions[Name]; ok {
+ if detail, ok := providerOptions.(*openai.ProviderFileOptions); ok {
+ imageURL.Detail = detail.ImageDetail
+ }
+ }
+
+ imageBlock := openaisdk.ChatCompletionContentPartImageParam{ImageURL: imageURL}
+ if cacheControl != nil {
+ imageBlock.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ content = append(content, openaisdk.ChatCompletionContentPartUnionParam{OfImageURL: &imageBlock})
+
+ case filePart.MediaType == "audio/wav":
+ // Handle WAV audio files
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ audioBlock := openaisdk.ChatCompletionContentPartInputAudioParam{
+ InputAudio: openaisdk.ChatCompletionContentPartInputAudioInputAudioParam{
+ Data: base64Encoded,
+ Format: "wav",
+ },
+ }
+ if cacheControl != nil {
+ audioBlock.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ content = append(content, openaisdk.ChatCompletionContentPartUnionParam{OfInputAudio: &audioBlock})
+
+ case filePart.MediaType == "audio/mpeg" || filePart.MediaType == "audio/mp3":
+ // Handle MP3 audio files
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ audioBlock := openaisdk.ChatCompletionContentPartInputAudioParam{
+ InputAudio: openaisdk.ChatCompletionContentPartInputAudioInputAudioParam{
+ Data: base64Encoded,
+ Format: "mp3",
+ },
+ }
+ if cacheControl != nil {
+ audioBlock.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ content = append(content, openaisdk.ChatCompletionContentPartUnionParam{OfInputAudio: &audioBlock})
+
+ case filePart.MediaType == "application/pdf":
+ // Handle PDF files
+ dataStr := string(filePart.Data)
+
+ // Check if data looks like a file ID (starts with "file-")
+ if strings.HasPrefix(dataStr, "file-") {
+ fileBlock := openaisdk.ChatCompletionContentPartFileParam{
+ File: openaisdk.ChatCompletionContentPartFileFileParam{
+ FileID: param.NewOpt(dataStr),
+ },
+ }
+
+ if cacheControl != nil {
+ fileBlock.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ content = append(content, openaisdk.ChatCompletionContentPartUnionParam{OfFile: &fileBlock})
+ } else {
+ // Handle as base64 data
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ data := "data:application/pdf;base64," + base64Encoded
+
+ filename := filePart.Filename
+ if filename == "" {
+ // Generate default filename based on content index
+ filename = fmt.Sprintf("part-%d.pdf", len(content))
+ }
+
+ fileBlock := openaisdk.ChatCompletionContentPartFileParam{
+ File: openaisdk.ChatCompletionContentPartFileFileParam{
+ Filename: param.NewOpt(filename),
+ FileData: param.NewOpt(data),
+ },
+ }
+ if cacheControl != nil {
+ fileBlock.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ content = append(content, openaisdk.ChatCompletionContentPartUnionParam{OfFile: &fileBlock})
+ }
+
+ default:
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: fmt.Sprintf("file part media type %s not supported", filePart.MediaType),
+ })
+ }
+ }
+ }
+ messages = append(messages, openaisdk.UserMessage(content))
+ case fantasy.MessageRoleAssistant:
+ // simple assistant message just text content
+ if len(msg.Content) == 1 && msg.Content[0].GetType() == fantasy.ContentTypeText {
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](msg.Content[0])
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message text part does not have the right type",
+ })
+ continue
+ }
+
+ assistantMsg := openaisdk.AssistantMessage(textPart.Text)
+ anthropicCache := anthropic.GetCacheControl(msg.ProviderOptions)
+ if anthropicCache != nil {
+ assistantMsg.OfAssistant.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": anthropicCache.Type,
+ },
+ })
+ }
+ messages = append(messages, assistantMsg)
+ continue
+ }
+ assistantMsg := openaisdk.ChatCompletionAssistantMessageParam{
+ Role: "assistant",
+ }
+ for i, c := range msg.Content {
+ isLastPart := i == len(msg.Content)-1
+ cacheControl := anthropic.GetCacheControl(c.Options())
+ if cacheControl == nil && isLastPart {
+ cacheControl = anthropic.GetCacheControl(msg.ProviderOptions)
+ }
+ switch c.GetType() {
+ case fantasy.ContentTypeText:
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message text part does not have the right type",
+ })
+ continue
+ }
+ // there is some text already there
+ if assistantMsg.Content.OfString.Valid() {
+ textPart.Text = assistantMsg.Content.OfString.Value + "\n" + textPart.Text
+ }
+ assistantMsg.Content = openaisdk.ChatCompletionAssistantMessageParamContentUnion{
+ OfString: param.NewOpt(textPart.Text),
+ }
+ if cacheControl != nil {
+ assistantMsg.Content.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ case fantasy.ContentTypeReasoning:
+ reasoningPart, ok := fantasy.AsContentType[fantasy.ReasoningPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message reasoning part does not have the right type",
+ })
+ continue
+ }
+ var reasoningDetails []ReasoningDetail
+ switch {
+ case strings.HasPrefix(model, "anthropic/") && reasoningPart.Text != "":
+ metadata := anthropic.GetReasoningMetadata(reasoningPart.Options())
+ if metadata == nil {
+ text := fmt.Sprintf("%s", reasoningPart.Text)
+ if assistantMsg.Content.OfString.Valid() {
+ text = assistantMsg.Content.OfString.Value + "\n" + text
+ }
+ // this reasoning did not come from anthropic just add a text content
+ assistantMsg.Content = openaisdk.ChatCompletionAssistantMessageParamContentUnion{
+ OfString: param.NewOpt(text),
+ }
+ if cacheControl != nil {
+ assistantMsg.Content.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ continue
+ }
+ reasoningDetails = append(reasoningDetails, ReasoningDetail{
+ Format: "anthropic-claude-v1",
+ Type: "reasoning.text",
+ Text: reasoningPart.Text,
+ Signature: metadata.Signature,
+ })
+ data, _ := json.Marshal(reasoningDetails)
+ reasoningDetailsMap := []map[string]any{}
+ _ = json.Unmarshal(data, &reasoningDetailsMap)
+ assistantMsg.SetExtraFields(map[string]any{
+ "reasoning_details": reasoningDetailsMap,
+ "reasoning": reasoningPart.Text,
+ })
+ case strings.HasPrefix(model, "openai/"):
+ metadata := openai.GetReasoningMetadata(reasoningPart.Options())
+ if metadata == nil {
+ text := fmt.Sprintf("%s", reasoningPart.Text)
+ if assistantMsg.Content.OfString.Valid() {
+ text = assistantMsg.Content.OfString.Value + "\n" + text
+ }
+ // this reasoning did not come from anthropic just add a text content
+ assistantMsg.Content = openaisdk.ChatCompletionAssistantMessageParamContentUnion{
+ OfString: param.NewOpt(text),
+ }
+ continue
+ }
+ for inx, summary := range metadata.Summary {
+ if summary == "" {
+ continue
+ }
+ reasoningDetails = append(reasoningDetails, ReasoningDetail{
+ Type: "reasoning.summary",
+ Format: "openai-responses-v1",
+ Summary: summary,
+ Index: inx,
+ })
+ }
+ reasoningDetails = append(reasoningDetails, ReasoningDetail{
+ Type: "reasoning.encrypted",
+ Format: "openai-responses-v1",
+ Data: *metadata.EncryptedContent,
+ ID: metadata.ItemID,
+ })
+ data, _ := json.Marshal(reasoningDetails)
+ reasoningDetailsMap := []map[string]any{}
+ _ = json.Unmarshal(data, &reasoningDetailsMap)
+ assistantMsg.SetExtraFields(map[string]any{
+ "reasoning_details": reasoningDetailsMap,
+ })
+ case strings.HasPrefix(model, "xai/"):
+ metadata := openai.GetReasoningMetadata(reasoningPart.Options())
+ if metadata == nil {
+ text := fmt.Sprintf("%s", reasoningPart.Text)
+ if assistantMsg.Content.OfString.Valid() {
+ text = assistantMsg.Content.OfString.Value + "\n" + text
+ }
+ // this reasoning did not come from anthropic just add a text content
+ assistantMsg.Content = openaisdk.ChatCompletionAssistantMessageParamContentUnion{
+ OfString: param.NewOpt(text),
+ }
+ continue
+ }
+ for inx, summary := range metadata.Summary {
+ if summary == "" {
+ continue
+ }
+ reasoningDetails = append(reasoningDetails, ReasoningDetail{
+ Type: "reasoning.summary",
+ Format: "xai-responses-v1",
+ Summary: summary,
+ Index: inx,
+ })
+ }
+ reasoningDetails = append(reasoningDetails, ReasoningDetail{
+ Type: "reasoning.encrypted",
+ Format: "xai-responses-v1",
+ Data: *metadata.EncryptedContent,
+ ID: metadata.ItemID,
+ })
+ data, _ := json.Marshal(reasoningDetails)
+ reasoningDetailsMap := []map[string]any{}
+ _ = json.Unmarshal(data, &reasoningDetailsMap)
+ assistantMsg.SetExtraFields(map[string]any{
+ "reasoning_details": reasoningDetailsMap,
+ })
+ case strings.HasPrefix(model, "google/"):
+ metadata := google.GetReasoningMetadata(reasoningPart.Options())
+ if metadata == nil {
+ text := fmt.Sprintf("%s", reasoningPart.Text)
+ if assistantMsg.Content.OfString.Valid() {
+ text = assistantMsg.Content.OfString.Value + "\n" + text
+ }
+ // this reasoning did not come from anthropic just add a text content
+ assistantMsg.Content = openaisdk.ChatCompletionAssistantMessageParamContentUnion{
+ OfString: param.NewOpt(text),
+ }
+ continue
+ }
+ if reasoningPart.Text != "" {
+ reasoningDetails = append(reasoningDetails, ReasoningDetail{
+ Type: "reasoning.text",
+ Format: "google-gemini-v1",
+ Text: reasoningPart.Text,
+ })
+ }
+ reasoningDetails = append(reasoningDetails, ReasoningDetail{
+ Type: "reasoning.encrypted",
+ Format: "google-gemini-v1",
+ Data: metadata.Signature,
+ ID: metadata.ToolID,
+ })
+ data, _ := json.Marshal(reasoningDetails)
+ reasoningDetailsMap := []map[string]any{}
+ _ = json.Unmarshal(data, &reasoningDetailsMap)
+ assistantMsg.SetExtraFields(map[string]any{
+ "reasoning_details": reasoningDetailsMap,
+ })
+ default:
+ reasoningDetails = append(reasoningDetails, ReasoningDetail{
+ Type: "reasoning.text",
+ Text: reasoningPart.Text,
+ Format: "unknown",
+ })
+ data, _ := json.Marshal(reasoningDetails)
+ reasoningDetailsMap := []map[string]any{}
+ _ = json.Unmarshal(data, &reasoningDetailsMap)
+ assistantMsg.SetExtraFields(map[string]any{
+ "reasoning_details": reasoningDetailsMap,
+ })
+ }
+ case fantasy.ContentTypeToolCall:
+ toolCallPart, ok := fantasy.AsContentType[fantasy.ToolCallPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message tool part does not have the right type",
+ })
+ continue
+ }
+ tc := openaisdk.ChatCompletionMessageToolCallUnionParam{
+ OfFunction: &openaisdk.ChatCompletionMessageFunctionToolCallParam{
+ ID: toolCallPart.ToolCallID,
+ Type: "function",
+ Function: openaisdk.ChatCompletionMessageFunctionToolCallFunctionParam{
+ Name: toolCallPart.ToolName,
+ Arguments: toolCallPart.Input,
+ },
+ },
+ }
+ if cacheControl != nil {
+ tc.OfFunction.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ assistantMsg.ToolCalls = append(assistantMsg.ToolCalls, tc)
+ }
+ }
+ messages = append(messages, openaisdk.ChatCompletionMessageParamUnion{
+ OfAssistant: &assistantMsg,
+ })
+ case fantasy.MessageRoleTool:
+ for i, c := range msg.Content {
+ isLastPart := i == len(msg.Content)-1
+ cacheControl := anthropic.GetCacheControl(c.Options())
+ if cacheControl == nil && isLastPart {
+ cacheControl = anthropic.GetCacheControl(msg.ProviderOptions)
+ }
+ if c.GetType() != fantasy.ContentTypeToolResult {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool message can only have tool result content",
+ })
+ continue
+ }
+
+ toolResultPart, ok := fantasy.AsContentType[fantasy.ToolResultPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool message result part does not have the right type",
+ })
+ continue
+ }
+
+ switch toolResultPart.Output.GetType() {
+ case fantasy.ToolResultContentTypeText:
+ output, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentText](toolResultPart.Output)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool result output does not have the right type",
+ })
+ continue
+ }
+ tr := openaisdk.ToolMessage(output.Text, toolResultPart.ToolCallID)
+ if cacheControl != nil {
+ tr.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ messages = append(messages, tr)
+ case fantasy.ToolResultContentTypeError:
+ // TODO: check if better handling is needed
+ output, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentError](toolResultPart.Output)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool result output does not have the right type",
+ })
+ continue
+ }
+ tr := openaisdk.ToolMessage(output.Error.Error(), toolResultPart.ToolCallID)
+ if cacheControl != nil {
+ tr.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ messages = append(messages, tr)
+ }
+ }
+ }
+ }
+ return messages, warnings
+}
diff --git a/internal/fantasy/providers/openrouter/openrouter.go b/internal/fantasy/providers/openrouter/openrouter.go
new file mode 100644
index 000000000..bd0e700af
--- /dev/null
+++ b/internal/fantasy/providers/openrouter/openrouter.go
@@ -0,0 +1,113 @@
+// Package openrouter provides an implementation of the fantasy AI SDK for OpenRouter's language models.
+package openrouter
+
+import (
+ "encoding/json"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/openai"
+ "github.com/openai/openai-go/v2/option"
+)
+
+type options struct {
+ openaiOptions []openai.Option
+ languageModelOptions []openai.LanguageModelOption
+ objectMode fantasy.ObjectMode
+}
+
+const (
+ // DefaultURL is the default URL for the OpenRouter API.
+ DefaultURL = "https://openrouter.ai/api/v1"
+ // Name is the name of the OpenRouter provider.
+ Name = "openrouter"
+)
+
+// Option defines a function that configures OpenRouter provider options.
+type Option = func(*options)
+
+// New creates a new OpenRouter provider with the given options.
+func New(opts ...Option) (fantasy.Provider, error) {
+ providerOptions := options{
+ openaiOptions: []openai.Option{
+ openai.WithName(Name),
+ openai.WithBaseURL(DefaultURL),
+ },
+ languageModelOptions: []openai.LanguageModelOption{
+ openai.WithLanguageModelPrepareCallFunc(languagePrepareModelCall),
+ openai.WithLanguageModelUsageFunc(languageModelUsage),
+ openai.WithLanguageModelStreamUsageFunc(languageModelStreamUsage),
+ openai.WithLanguageModelStreamExtraFunc(languageModelStreamExtra),
+ openai.WithLanguageModelExtraContentFunc(languageModelExtraContent),
+ openai.WithLanguageModelToPromptFunc(languageModelToPrompt),
+ },
+ objectMode: fantasy.ObjectModeTool, // Default to tool mode for openrouter
+ }
+ for _, o := range opts {
+ o(&providerOptions)
+ }
+
+ // Handle object mode: convert unsupported modes to tool
+ // OpenRouter doesn't support native JSON mode, so we use tool or text
+ objectMode := providerOptions.objectMode
+ if objectMode == fantasy.ObjectModeAuto || objectMode == fantasy.ObjectModeJSON {
+ objectMode = fantasy.ObjectModeTool
+ }
+
+ providerOptions.openaiOptions = append(
+ providerOptions.openaiOptions,
+ openai.WithLanguageModelOptions(providerOptions.languageModelOptions...),
+ openai.WithObjectMode(objectMode),
+ )
+ return openai.New(providerOptions.openaiOptions...)
+}
+
+// WithAPIKey sets the API key for the OpenRouter provider.
+func WithAPIKey(apiKey string) Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithAPIKey(apiKey))
+ }
+}
+
+// WithName sets the name for the OpenRouter provider.
+func WithName(name string) Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithName(name))
+ }
+}
+
+// WithHeaders sets the headers for the OpenRouter provider.
+func WithHeaders(headers map[string]string) Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithHeaders(headers))
+ }
+}
+
+// WithHTTPClient sets the HTTP client for the OpenRouter provider.
+func WithHTTPClient(client option.HTTPClient) Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithHTTPClient(client))
+ }
+}
+
+// WithObjectMode sets the object generation mode for the OpenRouter provider.
+// Supported modes: ObjectModeTool, ObjectModeText.
+// ObjectModeAuto and ObjectModeJSON are automatically converted to ObjectModeTool
+// since OpenRouter doesn't support native JSON mode.
+func WithObjectMode(om fantasy.ObjectMode) Option {
+ return func(o *options) {
+ o.objectMode = om
+ }
+}
+
+func structToMapJSON(s any) (map[string]any, error) {
+ var result map[string]any
+ jsonBytes, err := json.Marshal(s)
+ if err != nil {
+ return nil, err
+ }
+ err = json.Unmarshal(jsonBytes, &result)
+ if err != nil {
+ return nil, err
+ }
+ return result, nil
+}
diff --git a/internal/fantasy/providers/openrouter/provider_options.go b/internal/fantasy/providers/openrouter/provider_options.go
new file mode 100644
index 000000000..ed2d8f5ed
--- /dev/null
+++ b/internal/fantasy/providers/openrouter/provider_options.go
@@ -0,0 +1,210 @@
+// Package openrouter provides an implementation of the fantasy AI SDK for OpenRouter's language models.
+package openrouter
+
+import (
+ "encoding/json"
+
+ "charm.land/fantasy"
+)
+
+// ReasoningEffort represents the reasoning effort level for OpenRouter models.
+type ReasoningEffort string
+
+const (
+ // ReasoningEffortLow represents low reasoning effort.
+ ReasoningEffortLow ReasoningEffort = "low"
+ // ReasoningEffortMedium represents medium reasoning effort.
+ ReasoningEffortMedium ReasoningEffort = "medium"
+ // ReasoningEffortHigh represents high reasoning effort.
+ ReasoningEffortHigh ReasoningEffort = "high"
+)
+
+// Global type identifiers for OpenRouter-specific provider data.
+const (
+ TypeProviderOptions = Name + ".options"
+ TypeProviderMetadata = Name + ".metadata"
+)
+
+// Register OpenRouter provider-specific types with the global registry.
+func init() {
+ fantasy.RegisterProviderType(TypeProviderOptions, func(data []byte) (fantasy.ProviderOptionsData, error) {
+ var v ProviderOptions
+ if err := json.Unmarshal(data, &v); err != nil {
+ return nil, err
+ }
+ return &v, nil
+ })
+ fantasy.RegisterProviderType(TypeProviderMetadata, func(data []byte) (fantasy.ProviderOptionsData, error) {
+ var v ProviderMetadata
+ if err := json.Unmarshal(data, &v); err != nil {
+ return nil, err
+ }
+ return &v, nil
+ })
+}
+
+// PromptTokensDetails represents details about prompt tokens for OpenRouter.
+type PromptTokensDetails struct {
+ CachedTokens int64 `json:"cached_tokens"`
+}
+
+// CompletionTokensDetails represents details about completion tokens for OpenRouter.
+type CompletionTokensDetails struct {
+ ReasoningTokens int64 `json:"reasoning_tokens"`
+}
+
+// CostDetails represents cost details for OpenRouter.
+type CostDetails struct {
+ UpstreamInferenceCost float64 `json:"upstream_inference_cost"`
+ UpstreamInferencePromptCost float64 `json:"upstream_inference_prompt_cost"`
+ UpstreamInferenceCompletionsCost float64 `json:"upstream_inference_completions_cost"`
+}
+
+// UsageAccounting represents usage accounting details for OpenRouter.
+type UsageAccounting struct {
+ PromptTokens int64 `json:"prompt_tokens"`
+ PromptTokensDetails PromptTokensDetails `json:"prompt_tokens_details"`
+ CompletionTokens int64 `json:"completion_tokens"`
+ CompletionTokensDetails CompletionTokensDetails `json:"completion_tokens_details"`
+ TotalTokens int64 `json:"total_tokens"`
+ Cost float64 `json:"cost"`
+ CostDetails CostDetails `json:"cost_details"`
+}
+
+// ProviderMetadata represents metadata from OpenRouter provider.
+type ProviderMetadata struct {
+ Provider string `json:"provider"`
+ Usage UsageAccounting `json:"usage"`
+}
+
+// Options implements the ProviderOptionsData interface for ProviderMetadata.
+func (*ProviderMetadata) Options() {}
+
+// MarshalJSON implements custom JSON marshaling with type info for ProviderMetadata.
+func (m ProviderMetadata) MarshalJSON() ([]byte, error) {
+ type plain ProviderMetadata
+ return fantasy.MarshalProviderType(TypeProviderMetadata, plain(m))
+}
+
+// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderMetadata.
+func (m *ProviderMetadata) UnmarshalJSON(data []byte) error {
+ type plain ProviderMetadata
+ var p plain
+ if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+ return err
+ }
+ *m = ProviderMetadata(p)
+ return nil
+}
+
+// ReasoningOptions represents reasoning options for OpenRouter.
+type ReasoningOptions struct {
+ // Whether reasoning is enabled
+ Enabled *bool `json:"enabled,omitempty"`
+ // Whether to exclude reasoning from the response
+ Exclude *bool `json:"exclude,omitempty"`
+ // Maximum number of tokens to use for reasoning
+ MaxTokens *int64 `json:"max_tokens,omitempty"`
+ // Reasoning effort level: "low" | "medium" | "high"
+ Effort *ReasoningEffort `json:"effort,omitempty"`
+}
+
+// Provider represents provider routing preferences for OpenRouter.
+type Provider struct {
+ // List of provider slugs to try in order (e.g. ["anthropic", "openai"])
+ Order []string `json:"order,omitempty"`
+ // Whether to allow backup providers when primary is unavailable (default: true)
+ AllowFallbacks *bool `json:"allow_fallbacks,omitempty"`
+ // Only use providers that support all parameters in your request (default: false)
+ RequireParameters *bool `json:"require_parameters,omitempty"`
+ // Control whether to use providers that may store data: "allow" | "deny"
+ DataCollection *string `json:"data_collection,omitempty"`
+ // List of provider slugs to allow for this request
+ Only []string `json:"only,omitempty"`
+ // List of provider slugs to skip for this request
+ Ignore []string `json:"ignore,omitempty"`
+ // List of quantization levels to filter by (e.g. ["int4", "int8"])
+ Quantizations []string `json:"quantizations,omitempty"`
+ // Sort providers by "price" | "throughput" | "latency"
+ Sort *string `json:"sort,omitempty"`
+}
+
+// ProviderOptions represents additional options for OpenRouter provider.
+type ProviderOptions struct {
+ Reasoning *ReasoningOptions `json:"reasoning,omitempty"`
+ ExtraBody map[string]any `json:"extra_body,omitempty"`
+ IncludeUsage *bool `json:"include_usage,omitempty"`
+ // Modify the likelihood of specified tokens appearing in the completion.
+ // Accepts a map that maps tokens (specified by their token ID) to an associated bias value from -100 to 100.
+ // The bias is added to the logits generated by the model prior to sampling.
+ LogitBias map[string]int64 `json:"logit_bias,omitempty"`
+ // Return the log probabilities of the tokens. Including logprobs will increase the response size.
+ // Setting to true will return the log probabilities of the tokens that were generated.
+ LogProbs *bool `json:"log_probs,omitempty"`
+ // Whether to enable parallel function calling during tool use. Default to true.
+ ParallelToolCalls *bool `json:"parallel_tool_calls,omitempty"`
+ // A unique identifier representing your end-user, which can help OpenRouter to monitor and detect abuse.
+ User *string `json:"user,omitempty"`
+ // Provider routing preferences to control request routing behavior
+ Provider *Provider `json:"provider,omitempty"`
+ // TODO: add the web search plugin config
+}
+
+// Options implements the ProviderOptionsData interface for ProviderOptions.
+func (*ProviderOptions) Options() {}
+
+// MarshalJSON implements custom JSON marshaling with type info for ProviderOptions.
+func (o ProviderOptions) MarshalJSON() ([]byte, error) {
+ type plain ProviderOptions
+ return fantasy.MarshalProviderType(TypeProviderOptions, plain(o))
+}
+
+// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderOptions.
+func (o *ProviderOptions) UnmarshalJSON(data []byte) error {
+ type plain ProviderOptions
+ var p plain
+ if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+ return err
+ }
+ *o = ProviderOptions(p)
+ return nil
+}
+
+// ReasoningDetail represents a reasoning detail for OpenRouter.
+type ReasoningDetail struct {
+ ID string `json:"id,omitempty"`
+ Type string `json:"type,omitempty"`
+ Text string `json:"text,omitempty"`
+ Data string `json:"data,omitempty"`
+ Format string `json:"format,omitempty"`
+ Summary string `json:"summary,omitempty"`
+ Signature string `json:"signature,omitempty"`
+ Index int `json:"index"`
+}
+
+// ReasoningData represents reasoning data for OpenRouter.
+type ReasoningData struct {
+ Reasoning string `json:"reasoning"`
+ ReasoningDetails []ReasoningDetail `json:"reasoning_details"`
+}
+
+// ReasoningEffortOption creates a pointer to a ReasoningEffort value for OpenRouter.
+func ReasoningEffortOption(e ReasoningEffort) *ReasoningEffort {
+ return &e
+}
+
+// NewProviderOptions creates new provider options for OpenRouter.
+func NewProviderOptions(opts *ProviderOptions) fantasy.ProviderOptions {
+ return fantasy.ProviderOptions{
+ Name: opts,
+ }
+}
+
+// ParseOptions parses provider options from a map for OpenRouter.
+func ParseOptions(data map[string]any) (*ProviderOptions, error) {
+ var options ProviderOptions
+ if err := fantasy.ParseOptions(data, &options); err != nil {
+ return nil, err
+ }
+ return &options, nil
+}
diff --git a/internal/fantasy/providers/vercel/language_model_hooks.go b/internal/fantasy/providers/vercel/language_model_hooks.go
new file mode 100644
index 000000000..d243e57f6
--- /dev/null
+++ b/internal/fantasy/providers/vercel/language_model_hooks.go
@@ -0,0 +1,1052 @@
+package vercel
+
+import (
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "maps"
+ "strings"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/anthropic"
+ "charm.land/fantasy/providers/google"
+ openaipkg "charm.land/fantasy/providers/openai"
+ openaisdk "github.com/openai/openai-go/v2"
+ "github.com/openai/openai-go/v2/packages/param"
+)
+
+const reasoningStartedCtx = "reasoning_started"
+
+type currentReasoningState struct {
+ metadata *openaipkg.ResponsesReasoningMetadata
+ googleMetadata *google.ReasoningMetadata
+ googleText string
+ anthropicSig string
+}
+
+func languagePrepareModelCall(_ fantasy.LanguageModel, params *openaisdk.ChatCompletionNewParams, call fantasy.Call) ([]fantasy.CallWarning, error) {
+ providerOptions := &ProviderOptions{}
+ if v, ok := call.ProviderOptions[Name]; ok {
+ providerOptions, ok = v.(*ProviderOptions)
+ if !ok {
+ return nil, &fantasy.Error{Title: "invalid argument", Message: "vercel provider options should be *vercel.ProviderOptions"}
+ }
+ }
+
+ extraFields := make(map[string]any)
+
+ // Handle reasoning options
+ if providerOptions.Reasoning != nil {
+ data, err := structToMapJSON(providerOptions.Reasoning)
+ if err != nil {
+ return nil, err
+ }
+ extraFields["reasoning"] = data
+ }
+
+ // Handle provider options for gateway routing
+ if providerOptions.ProviderOptions != nil {
+ data, err := structToMapJSON(providerOptions.ProviderOptions)
+ if err != nil {
+ return nil, err
+ }
+ extraFields["providerOptions"] = map[string]any{
+ "gateway": data,
+ }
+ }
+
+ // Handle BYOK (Bring Your Own Key)
+ if providerOptions.BYOK != nil {
+ data, err := structToMapJSON(providerOptions.BYOK)
+ if err != nil {
+ return nil, err
+ }
+ if gatewayOpts, ok := extraFields["providerOptions"].(map[string]any); ok {
+ gatewayOpts["byok"] = data
+ } else {
+ extraFields["providerOptions"] = map[string]any{
+ "gateway": map[string]any{
+ "byok": data,
+ },
+ }
+ }
+ }
+
+ // Handle standard OpenAI options
+ if providerOptions.LogitBias != nil {
+ params.LogitBias = providerOptions.LogitBias
+ }
+ if providerOptions.LogProbs != nil {
+ params.Logprobs = param.NewOpt(*providerOptions.LogProbs)
+ }
+ if providerOptions.TopLogProbs != nil {
+ params.TopLogprobs = param.NewOpt(*providerOptions.TopLogProbs)
+ }
+ if providerOptions.User != nil {
+ params.User = param.NewOpt(*providerOptions.User)
+ }
+ if providerOptions.ParallelToolCalls != nil {
+ params.ParallelToolCalls = param.NewOpt(*providerOptions.ParallelToolCalls)
+ }
+
+ // Handle model fallbacks - direct models field
+ if providerOptions.ProviderOptions != nil && len(providerOptions.ProviderOptions.Models) > 0 {
+ extraFields["models"] = providerOptions.ProviderOptions.Models
+ }
+
+ maps.Copy(extraFields, providerOptions.ExtraBody)
+ params.SetExtraFields(extraFields)
+ return nil, nil
+}
+
+func languageModelExtraContent(choice openaisdk.ChatCompletionChoice) []fantasy.Content {
+ content := make([]fantasy.Content, 0)
+ reasoningData := ReasoningData{}
+ err := json.Unmarshal([]byte(choice.Message.RawJSON()), &reasoningData)
+ if err != nil {
+ return content
+ }
+
+ responsesReasoningBlocks := make([]openaipkg.ResponsesReasoningMetadata, 0)
+ anthropicReasoningBlocks := make([]struct {
+ text string
+ metadata *anthropic.ReasoningOptionMetadata
+ }, 0)
+ googleReasoningBlocks := make([]struct {
+ text string
+ metadata *google.ReasoningMetadata
+ }, 0)
+ otherReasoning := make([]string, 0)
+
+ for _, detail := range reasoningData.ReasoningDetails {
+ if strings.HasPrefix(detail.Format, "openai-responses") || strings.HasPrefix(detail.Format, "xai-responses") {
+ var thinkingBlock openaipkg.ResponsesReasoningMetadata
+ if len(responsesReasoningBlocks)-1 >= detail.Index {
+ thinkingBlock = responsesReasoningBlocks[detail.Index]
+ } else {
+ thinkingBlock = openaipkg.ResponsesReasoningMetadata{}
+ responsesReasoningBlocks = append(responsesReasoningBlocks, thinkingBlock)
+ }
+
+ switch detail.Type {
+ case "reasoning.summary":
+ thinkingBlock.Summary = append(thinkingBlock.Summary, detail.Summary)
+ case "reasoning.encrypted":
+ thinkingBlock.EncryptedContent = &detail.Data
+ }
+ if detail.ID != "" {
+ thinkingBlock.ItemID = detail.ID
+ }
+ responsesReasoningBlocks[detail.Index] = thinkingBlock
+ continue
+ }
+
+ if strings.HasPrefix(detail.Format, "google-gemini") {
+ var thinkingBlock struct {
+ text string
+ metadata *google.ReasoningMetadata
+ }
+ if len(googleReasoningBlocks)-1 >= detail.Index {
+ thinkingBlock = googleReasoningBlocks[detail.Index]
+ } else {
+ thinkingBlock = struct {
+ text string
+ metadata *google.ReasoningMetadata
+ }{metadata: &google.ReasoningMetadata{}}
+ googleReasoningBlocks = append(googleReasoningBlocks, thinkingBlock)
+ }
+
+ switch detail.Type {
+ case "reasoning.text":
+ thinkingBlock.text = detail.Text
+ case "reasoning.encrypted":
+ thinkingBlock.metadata.Signature = detail.Data
+ thinkingBlock.metadata.ToolID = detail.ID
+ }
+ googleReasoningBlocks[detail.Index] = thinkingBlock
+ continue
+ }
+
+ if strings.HasPrefix(detail.Format, "anthropic-claude") {
+ anthropicReasoningBlocks = append(anthropicReasoningBlocks, struct {
+ text string
+ metadata *anthropic.ReasoningOptionMetadata
+ }{
+ text: detail.Text,
+ metadata: &anthropic.ReasoningOptionMetadata{
+ Signature: detail.Signature,
+ },
+ })
+ continue
+ }
+
+ otherReasoning = append(otherReasoning, detail.Text)
+ }
+
+ // Fallback to simple reasoning field if no details
+ if reasoningData.Reasoning != "" && len(reasoningData.ReasoningDetails) == 0 {
+ otherReasoning = append(otherReasoning, reasoningData.Reasoning)
+ }
+
+ for _, block := range responsesReasoningBlocks {
+ if len(block.Summary) == 0 {
+ block.Summary = []string{""}
+ }
+ content = append(content, fantasy.ReasoningContent{
+ Text: strings.Join(block.Summary, "\n"),
+ ProviderMetadata: fantasy.ProviderMetadata{
+ openaipkg.Name: &block,
+ },
+ })
+ }
+
+ for _, block := range anthropicReasoningBlocks {
+ content = append(content, fantasy.ReasoningContent{
+ Text: block.text,
+ ProviderMetadata: fantasy.ProviderMetadata{
+ anthropic.Name: block.metadata,
+ },
+ })
+ }
+
+ for _, block := range googleReasoningBlocks {
+ content = append(content, fantasy.ReasoningContent{
+ Text: block.text,
+ ProviderMetadata: fantasy.ProviderMetadata{
+ google.Name: block.metadata,
+ },
+ })
+ }
+
+ for _, reasoning := range otherReasoning {
+ if reasoning != "" {
+ content = append(content, fantasy.ReasoningContent{
+ Text: reasoning,
+ })
+ }
+ }
+
+ return content
+}
+
+func extractReasoningContext(ctx map[string]any) *currentReasoningState {
+ reasoningStarted, ok := ctx[reasoningStartedCtx]
+ if !ok {
+ return nil
+ }
+ state, ok := reasoningStarted.(*currentReasoningState)
+ if !ok {
+ return nil
+ }
+ return state
+}
+
+func languageModelStreamExtra(chunk openaisdk.ChatCompletionChunk, yield func(fantasy.StreamPart) bool, ctx map[string]any) (map[string]any, bool) {
+ if len(chunk.Choices) == 0 {
+ return ctx, true
+ }
+
+ currentState := extractReasoningContext(ctx)
+
+ inx := 0
+ choice := chunk.Choices[inx]
+ reasoningData := ReasoningData{}
+ err := json.Unmarshal([]byte(choice.Delta.RawJSON()), &reasoningData)
+ if err != nil {
+ yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeError,
+ Error: &fantasy.Error{Title: "stream error", Message: "error unmarshalling delta", Cause: err},
+ })
+ return ctx, false
+ }
+
+ // Reasoning Start
+ if currentState == nil {
+ if len(reasoningData.ReasoningDetails) == 0 && reasoningData.Reasoning == "" {
+ return ctx, true
+ }
+
+ var metadata fantasy.ProviderMetadata
+ currentState = ¤tReasoningState{}
+
+ if len(reasoningData.ReasoningDetails) > 0 {
+ detail := reasoningData.ReasoningDetails[0]
+
+ if strings.HasPrefix(detail.Format, "openai-responses") || strings.HasPrefix(detail.Format, "xai-responses") {
+ currentState.metadata = &openaipkg.ResponsesReasoningMetadata{
+ Summary: []string{detail.Summary},
+ }
+ metadata = fantasy.ProviderMetadata{
+ openaipkg.Name: currentState.metadata,
+ }
+ if detail.Data != "" {
+ shouldContinue := yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningStart,
+ ID: fmt.Sprintf("%d", inx),
+ Delta: detail.Summary,
+ ProviderMetadata: metadata,
+ })
+ if !shouldContinue {
+ return ctx, false
+ }
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: fmt.Sprintf("%d", inx),
+ ProviderMetadata: fantasy.ProviderMetadata{
+ openaipkg.Name: &openaipkg.ResponsesReasoningMetadata{
+ Summary: []string{detail.Summary},
+ EncryptedContent: &detail.Data,
+ ItemID: detail.ID,
+ },
+ },
+ })
+ }
+ }
+
+ if strings.HasPrefix(detail.Format, "google-gemini") {
+ if detail.Type == "reasoning.encrypted" {
+ ctx[reasoningStartedCtx] = nil
+ if !yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningStart,
+ ID: fmt.Sprintf("%d", inx),
+ }) {
+ return ctx, false
+ }
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: fmt.Sprintf("%d", inx),
+ ProviderMetadata: fantasy.ProviderMetadata{
+ google.Name: &google.ReasoningMetadata{
+ Signature: detail.Data,
+ ToolID: detail.ID,
+ },
+ },
+ })
+ }
+ currentState.googleMetadata = &google.ReasoningMetadata{}
+ currentState.googleText = detail.Text
+ metadata = fantasy.ProviderMetadata{
+ google.Name: currentState.googleMetadata,
+ }
+ }
+
+ if strings.HasPrefix(detail.Format, "anthropic-claude") {
+ currentState.anthropicSig = detail.Signature
+ }
+ }
+
+ ctx[reasoningStartedCtx] = currentState
+ delta := reasoningData.Reasoning
+ if len(reasoningData.ReasoningDetails) > 0 {
+ delta = reasoningData.ReasoningDetails[0].Summary
+ if strings.HasPrefix(reasoningData.ReasoningDetails[0].Format, "google-gemini") {
+ delta = reasoningData.ReasoningDetails[0].Text
+ }
+ if strings.HasPrefix(reasoningData.ReasoningDetails[0].Format, "anthropic-claude") {
+ delta = reasoningData.ReasoningDetails[0].Text
+ }
+ }
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningStart,
+ ID: fmt.Sprintf("%d", inx),
+ Delta: delta,
+ ProviderMetadata: metadata,
+ })
+ }
+
+ if len(reasoningData.ReasoningDetails) == 0 && reasoningData.Reasoning == "" {
+ if choice.Delta.Content != "" || len(choice.Delta.ToolCalls) > 0 {
+ ctx[reasoningStartedCtx] = nil
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: fmt.Sprintf("%d", inx),
+ })
+ }
+ return ctx, true
+ }
+
+ if len(reasoningData.ReasoningDetails) > 0 {
+ detail := reasoningData.ReasoningDetails[0]
+
+ if strings.HasPrefix(detail.Format, "openai-responses") || strings.HasPrefix(detail.Format, "xai-responses") {
+ if detail.Data != "" {
+ currentState.metadata.EncryptedContent = &detail.Data
+ currentState.metadata.ItemID = detail.ID
+ ctx[reasoningStartedCtx] = nil
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: fmt.Sprintf("%d", inx),
+ ProviderMetadata: fantasy.ProviderMetadata{
+ openaipkg.Name: currentState.metadata,
+ },
+ })
+ }
+ var textDelta string
+ if len(currentState.metadata.Summary)-1 >= detail.Index {
+ currentState.metadata.Summary[detail.Index] += detail.Summary
+ textDelta = detail.Summary
+ } else {
+ currentState.metadata.Summary = append(currentState.metadata.Summary, detail.Summary)
+ textDelta = "\n" + detail.Summary
+ }
+ ctx[reasoningStartedCtx] = currentState
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: fmt.Sprintf("%d", inx),
+ Delta: textDelta,
+ ProviderMetadata: fantasy.ProviderMetadata{
+ openaipkg.Name: currentState.metadata,
+ },
+ })
+ }
+
+ if strings.HasPrefix(detail.Format, "anthropic-claude") {
+ if detail.Signature != "" {
+ metadata := fantasy.ProviderMetadata{
+ anthropic.Name: &anthropic.ReasoningOptionMetadata{
+ Signature: detail.Signature,
+ },
+ }
+ shouldContinue := yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: fmt.Sprintf("%d", inx),
+ Delta: detail.Text,
+ ProviderMetadata: metadata,
+ })
+ if !shouldContinue {
+ return ctx, false
+ }
+ ctx[reasoningStartedCtx] = nil
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: fmt.Sprintf("%d", inx),
+ })
+ }
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: fmt.Sprintf("%d", inx),
+ Delta: detail.Text,
+ })
+ }
+
+ if strings.HasPrefix(detail.Format, "google-gemini") {
+ if detail.Type == "reasoning.text" {
+ currentState.googleText += detail.Text
+ ctx[reasoningStartedCtx] = currentState
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: fmt.Sprintf("%d", inx),
+ Delta: detail.Text,
+ })
+ }
+ if detail.Type == "reasoning.encrypted" {
+ currentState.googleMetadata.Signature = detail.Data
+ currentState.googleMetadata.ToolID = detail.ID
+ metadata := fantasy.ProviderMetadata{
+ google.Name: currentState.googleMetadata,
+ }
+ ctx[reasoningStartedCtx] = nil
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningEnd,
+ ID: fmt.Sprintf("%d", inx),
+ ProviderMetadata: metadata,
+ })
+ }
+ }
+
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: fmt.Sprintf("%d", inx),
+ Delta: detail.Text,
+ })
+ }
+
+ if reasoningData.Reasoning != "" {
+ return ctx, yield(fantasy.StreamPart{
+ Type: fantasy.StreamPartTypeReasoningDelta,
+ ID: fmt.Sprintf("%d", inx),
+ Delta: reasoningData.Reasoning,
+ })
+ }
+
+ return ctx, true
+}
+
+func languageModelUsage(response openaisdk.ChatCompletion) (fantasy.Usage, fantasy.ProviderOptionsData) {
+ if len(response.Choices) == 0 {
+ return fantasy.Usage{}, nil
+ }
+
+ usage := response.Usage
+ completionTokenDetails := usage.CompletionTokensDetails
+ promptTokenDetails := usage.PromptTokensDetails
+
+ var provider string
+ if p, ok := response.JSON.ExtraFields["provider"]; ok {
+ provider = p.Raw()
+ }
+
+ providerMetadata := &ProviderMetadata{
+ Provider: provider,
+ }
+
+ return fantasy.Usage{
+ InputTokens: usage.PromptTokens,
+ OutputTokens: usage.CompletionTokens,
+ TotalTokens: usage.TotalTokens,
+ ReasoningTokens: completionTokenDetails.ReasoningTokens,
+ CacheReadTokens: promptTokenDetails.CachedTokens,
+ }, providerMetadata
+}
+
+func languageModelStreamUsage(chunk openaisdk.ChatCompletionChunk, _ map[string]any, metadata fantasy.ProviderMetadata) (fantasy.Usage, fantasy.ProviderMetadata) {
+ usage := chunk.Usage
+ if usage.TotalTokens == 0 {
+ return fantasy.Usage{}, nil
+ }
+
+ streamProviderMetadata := &ProviderMetadata{}
+ if metadata != nil {
+ if providerMetadata, ok := metadata[Name]; ok {
+ converted, ok := providerMetadata.(*ProviderMetadata)
+ if ok {
+ streamProviderMetadata = converted
+ }
+ }
+ }
+
+ if p, ok := chunk.JSON.ExtraFields["provider"]; ok {
+ streamProviderMetadata.Provider = p.Raw()
+ }
+
+ completionTokenDetails := usage.CompletionTokensDetails
+ promptTokenDetails := usage.PromptTokensDetails
+ aiUsage := fantasy.Usage{
+ InputTokens: usage.PromptTokens,
+ OutputTokens: usage.CompletionTokens,
+ TotalTokens: usage.TotalTokens,
+ ReasoningTokens: completionTokenDetails.ReasoningTokens,
+ CacheReadTokens: promptTokenDetails.CachedTokens,
+ }
+
+ return aiUsage, fantasy.ProviderMetadata{
+ Name: streamProviderMetadata,
+ }
+}
+
+func languageModelToPrompt(prompt fantasy.Prompt, _, model string) ([]openaisdk.ChatCompletionMessageParamUnion, []fantasy.CallWarning) {
+ var messages []openaisdk.ChatCompletionMessageParamUnion
+ var warnings []fantasy.CallWarning
+
+ for _, msg := range prompt {
+ switch msg.Role {
+ case fantasy.MessageRoleSystem:
+ var systemPromptParts []string
+ for _, c := range msg.Content {
+ if c.GetType() != fantasy.ContentTypeText {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "system prompt can only have text content",
+ })
+ continue
+ }
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "system prompt text part does not have the right type",
+ })
+ continue
+ }
+ text := textPart.Text
+ if strings.TrimSpace(text) != "" {
+ systemPromptParts = append(systemPromptParts, textPart.Text)
+ }
+ }
+ if len(systemPromptParts) == 0 {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "system prompt has no text parts",
+ })
+ continue
+ }
+ systemMsg := openaisdk.SystemMessage(strings.Join(systemPromptParts, "\n"))
+ anthropicCache := anthropic.GetCacheControl(msg.ProviderOptions)
+ if anthropicCache != nil {
+ systemMsg.OfSystem.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": anthropicCache.Type,
+ },
+ })
+ }
+ messages = append(messages, systemMsg)
+
+ case fantasy.MessageRoleUser:
+ if len(msg.Content) == 1 && msg.Content[0].GetType() == fantasy.ContentTypeText {
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](msg.Content[0])
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "user message text part does not have the right type",
+ })
+ continue
+ }
+ userMsg := openaisdk.UserMessage(textPart.Text)
+ anthropicCache := anthropic.GetCacheControl(msg.ProviderOptions)
+ if anthropicCache != nil {
+ userMsg.OfUser.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": anthropicCache.Type,
+ },
+ })
+ }
+ messages = append(messages, userMsg)
+ continue
+ }
+
+ var content []openaisdk.ChatCompletionContentPartUnionParam
+ for i, c := range msg.Content {
+ isLastPart := i == len(msg.Content)-1
+ cacheControl := anthropic.GetCacheControl(c.Options())
+ if cacheControl == nil && isLastPart {
+ cacheControl = anthropic.GetCacheControl(msg.ProviderOptions)
+ }
+ switch c.GetType() {
+ case fantasy.ContentTypeText:
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "user message text part does not have the right type",
+ })
+ continue
+ }
+ part := openaisdk.ChatCompletionContentPartUnionParam{
+ OfText: &openaisdk.ChatCompletionContentPartTextParam{
+ Text: textPart.Text,
+ },
+ }
+ if cacheControl != nil {
+ part.OfText.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ content = append(content, part)
+ case fantasy.ContentTypeFile:
+ filePart, ok := fantasy.AsContentType[fantasy.FilePart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "user message file part does not have the right type",
+ })
+ continue
+ }
+ switch {
+ case strings.HasPrefix(filePart.MediaType, "image/"):
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ data := "data:" + filePart.MediaType + ";base64," + base64Encoded
+ imageURL := openaisdk.ChatCompletionContentPartImageImageURLParam{URL: data}
+ if providerOptions, ok := filePart.ProviderOptions[openaipkg.Name]; ok {
+ if detail, ok := providerOptions.(*openaipkg.ProviderFileOptions); ok {
+ imageURL.Detail = detail.ImageDetail
+ }
+ }
+ imageBlock := openaisdk.ChatCompletionContentPartImageParam{ImageURL: imageURL}
+ if cacheControl != nil {
+ imageBlock.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ content = append(content, openaisdk.ChatCompletionContentPartUnionParam{OfImageURL: &imageBlock})
+
+ case filePart.MediaType == "audio/wav":
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ audioBlock := openaisdk.ChatCompletionContentPartInputAudioParam{
+ InputAudio: openaisdk.ChatCompletionContentPartInputAudioInputAudioParam{
+ Data: base64Encoded,
+ Format: "wav",
+ },
+ }
+ if cacheControl != nil {
+ audioBlock.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ content = append(content, openaisdk.ChatCompletionContentPartUnionParam{OfInputAudio: &audioBlock})
+
+ case filePart.MediaType == "audio/mpeg" || filePart.MediaType == "audio/mp3":
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ audioBlock := openaisdk.ChatCompletionContentPartInputAudioParam{
+ InputAudio: openaisdk.ChatCompletionContentPartInputAudioInputAudioParam{
+ Data: base64Encoded,
+ Format: "mp3",
+ },
+ }
+ if cacheControl != nil {
+ audioBlock.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ content = append(content, openaisdk.ChatCompletionContentPartUnionParam{OfInputAudio: &audioBlock})
+
+ case filePart.MediaType == "application/pdf":
+ dataStr := string(filePart.Data)
+ if strings.HasPrefix(dataStr, "file-") {
+ fileBlock := openaisdk.ChatCompletionContentPartFileParam{
+ File: openaisdk.ChatCompletionContentPartFileFileParam{
+ FileID: param.NewOpt(dataStr),
+ },
+ }
+ if cacheControl != nil {
+ fileBlock.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ content = append(content, openaisdk.ChatCompletionContentPartUnionParam{OfFile: &fileBlock})
+ } else {
+ base64Encoded := base64.StdEncoding.EncodeToString(filePart.Data)
+ data := "data:application/pdf;base64," + base64Encoded
+ filename := filePart.Filename
+ if filename == "" {
+ filename = fmt.Sprintf("part-%d.pdf", len(content))
+ }
+ fileBlock := openaisdk.ChatCompletionContentPartFileParam{
+ File: openaisdk.ChatCompletionContentPartFileFileParam{
+ Filename: param.NewOpt(filename),
+ FileData: param.NewOpt(data),
+ },
+ }
+ if cacheControl != nil {
+ fileBlock.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ content = append(content, openaisdk.ChatCompletionContentPartUnionParam{OfFile: &fileBlock})
+ }
+
+ default:
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: fmt.Sprintf("file part media type %s not supported", filePart.MediaType),
+ })
+ }
+ }
+ }
+ if !hasVisibleUserContent(content) {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "dropping empty user message (contains neither user-facing content nor tool results)",
+ })
+ continue
+ }
+ messages = append(messages, openaisdk.UserMessage(content))
+
+ case fantasy.MessageRoleAssistant:
+ if len(msg.Content) == 1 && msg.Content[0].GetType() == fantasy.ContentTypeText {
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](msg.Content[0])
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message text part does not have the right type",
+ })
+ continue
+ }
+ assistantMsg := openaisdk.AssistantMessage(textPart.Text)
+ anthropicCache := anthropic.GetCacheControl(msg.ProviderOptions)
+ if anthropicCache != nil {
+ assistantMsg.OfAssistant.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": anthropicCache.Type,
+ },
+ })
+ }
+ messages = append(messages, assistantMsg)
+ continue
+ }
+
+ assistantMsg := openaisdk.ChatCompletionAssistantMessageParam{
+ Role: "assistant",
+ }
+ for i, c := range msg.Content {
+ isLastPart := i == len(msg.Content)-1
+ cacheControl := anthropic.GetCacheControl(c.Options())
+ if cacheControl == nil && isLastPart {
+ cacheControl = anthropic.GetCacheControl(msg.ProviderOptions)
+ }
+ switch c.GetType() {
+ case fantasy.ContentTypeText:
+ textPart, ok := fantasy.AsContentType[fantasy.TextPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message text part does not have the right type",
+ })
+ continue
+ }
+ if assistantMsg.Content.OfString.Valid() {
+ textPart.Text = assistantMsg.Content.OfString.Value + "\n" + textPart.Text
+ }
+ assistantMsg.Content = openaisdk.ChatCompletionAssistantMessageParamContentUnion{
+ OfString: param.NewOpt(textPart.Text),
+ }
+ if cacheControl != nil {
+ assistantMsg.Content.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ case fantasy.ContentTypeReasoning:
+ reasoningPart, ok := fantasy.AsContentType[fantasy.ReasoningPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message reasoning part does not have the right type",
+ })
+ continue
+ }
+ var reasoningDetails []ReasoningDetail
+ switch {
+ case strings.HasPrefix(model, "anthropic/") && reasoningPart.Text != "":
+ metadata := anthropic.GetReasoningMetadata(reasoningPart.Options())
+ if metadata == nil {
+ text := fmt.Sprintf("%s", reasoningPart.Text)
+ if assistantMsg.Content.OfString.Valid() {
+ text = assistantMsg.Content.OfString.Value + "\n" + text
+ }
+ assistantMsg.Content = openaisdk.ChatCompletionAssistantMessageParamContentUnion{
+ OfString: param.NewOpt(text),
+ }
+ if cacheControl != nil {
+ assistantMsg.Content.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ continue
+ }
+ reasoningDetails = append(reasoningDetails, ReasoningDetail{
+ Format: "anthropic-claude-v1",
+ Type: "reasoning.text",
+ Text: reasoningPart.Text,
+ Signature: metadata.Signature,
+ })
+ data, _ := json.Marshal(reasoningDetails)
+ reasoningDetailsMap := []map[string]any{}
+ _ = json.Unmarshal(data, &reasoningDetailsMap)
+ assistantMsg.SetExtraFields(map[string]any{
+ "reasoning_details": reasoningDetailsMap,
+ "reasoning": reasoningPart.Text,
+ })
+ case strings.HasPrefix(model, "openai/"):
+ metadata := openaipkg.GetReasoningMetadata(reasoningPart.Options())
+ if metadata == nil {
+ text := fmt.Sprintf("%s", reasoningPart.Text)
+ if assistantMsg.Content.OfString.Valid() {
+ text = assistantMsg.Content.OfString.Value + "\n" + text
+ }
+ assistantMsg.Content = openaisdk.ChatCompletionAssistantMessageParamContentUnion{
+ OfString: param.NewOpt(text),
+ }
+ continue
+ }
+ for inx, summary := range metadata.Summary {
+ if summary == "" {
+ continue
+ }
+ reasoningDetails = append(reasoningDetails, ReasoningDetail{
+ Type: "reasoning.summary",
+ Format: "openai-responses-v1",
+ Summary: summary,
+ Index: inx,
+ })
+ }
+ reasoningDetails = append(reasoningDetails, ReasoningDetail{
+ Type: "reasoning.encrypted",
+ Format: "openai-responses-v1",
+ Data: *metadata.EncryptedContent,
+ ID: metadata.ItemID,
+ })
+ data, _ := json.Marshal(reasoningDetails)
+ reasoningDetailsMap := []map[string]any{}
+ _ = json.Unmarshal(data, &reasoningDetailsMap)
+ assistantMsg.SetExtraFields(map[string]any{
+ "reasoning_details": reasoningDetailsMap,
+ })
+ case strings.HasPrefix(model, "google/"):
+ metadata := google.GetReasoningMetadata(reasoningPart.Options())
+ if metadata == nil {
+ text := fmt.Sprintf("%s", reasoningPart.Text)
+ if assistantMsg.Content.OfString.Valid() {
+ text = assistantMsg.Content.OfString.Value + "\n" + text
+ }
+ assistantMsg.Content = openaisdk.ChatCompletionAssistantMessageParamContentUnion{
+ OfString: param.NewOpt(text),
+ }
+ continue
+ }
+ if reasoningPart.Text != "" {
+ reasoningDetails = append(reasoningDetails, ReasoningDetail{
+ Type: "reasoning.text",
+ Format: "google-gemini-v1",
+ Text: reasoningPart.Text,
+ })
+ }
+ reasoningDetails = append(reasoningDetails, ReasoningDetail{
+ Type: "reasoning.encrypted",
+ Format: "google-gemini-v1",
+ Data: metadata.Signature,
+ ID: metadata.ToolID,
+ })
+ data, _ := json.Marshal(reasoningDetails)
+ reasoningDetailsMap := []map[string]any{}
+ _ = json.Unmarshal(data, &reasoningDetailsMap)
+ assistantMsg.SetExtraFields(map[string]any{
+ "reasoning_details": reasoningDetailsMap,
+ })
+ default:
+ reasoningDetails = append(reasoningDetails, ReasoningDetail{
+ Type: "reasoning.text",
+ Text: reasoningPart.Text,
+ Format: "unknown",
+ })
+ data, _ := json.Marshal(reasoningDetails)
+ reasoningDetailsMap := []map[string]any{}
+ _ = json.Unmarshal(data, &reasoningDetailsMap)
+ assistantMsg.SetExtraFields(map[string]any{
+ "reasoning_details": reasoningDetailsMap,
+ })
+ }
+ case fantasy.ContentTypeToolCall:
+ toolCallPart, ok := fantasy.AsContentType[fantasy.ToolCallPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "assistant message tool part does not have the right type",
+ })
+ continue
+ }
+ tc := openaisdk.ChatCompletionMessageToolCallUnionParam{
+ OfFunction: &openaisdk.ChatCompletionMessageFunctionToolCallParam{
+ ID: toolCallPart.ToolCallID,
+ Type: "function",
+ Function: openaisdk.ChatCompletionMessageFunctionToolCallFunctionParam{
+ Name: toolCallPart.ToolName,
+ Arguments: toolCallPart.Input,
+ },
+ },
+ }
+ if cacheControl != nil {
+ tc.OfFunction.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ assistantMsg.ToolCalls = append(assistantMsg.ToolCalls, tc)
+ }
+ }
+ messages = append(messages, openaisdk.ChatCompletionMessageParamUnion{
+ OfAssistant: &assistantMsg,
+ })
+
+ case fantasy.MessageRoleTool:
+ for i, c := range msg.Content {
+ isLastPart := i == len(msg.Content)-1
+ cacheControl := anthropic.GetCacheControl(c.Options())
+ if cacheControl == nil && isLastPart {
+ cacheControl = anthropic.GetCacheControl(msg.ProviderOptions)
+ }
+ if c.GetType() != fantasy.ContentTypeToolResult {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool message can only have tool result content",
+ })
+ continue
+ }
+ toolResultPart, ok := fantasy.AsContentType[fantasy.ToolResultPart](c)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool message result part does not have the right type",
+ })
+ continue
+ }
+ switch toolResultPart.Output.GetType() {
+ case fantasy.ToolResultContentTypeText:
+ output, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentText](toolResultPart.Output)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool result output does not have the right type",
+ })
+ continue
+ }
+ tr := openaisdk.ToolMessage(output.Text, toolResultPart.ToolCallID)
+ if cacheControl != nil {
+ tr.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ messages = append(messages, tr)
+ case fantasy.ToolResultContentTypeError:
+ output, ok := fantasy.AsToolResultOutputType[fantasy.ToolResultOutputContentError](toolResultPart.Output)
+ if !ok {
+ warnings = append(warnings, fantasy.CallWarning{
+ Type: fantasy.CallWarningTypeOther,
+ Message: "tool result output does not have the right type",
+ })
+ continue
+ }
+ tr := openaisdk.ToolMessage(output.Error.Error(), toolResultPart.ToolCallID)
+ if cacheControl != nil {
+ tr.SetExtraFields(map[string]any{
+ "cache_control": map[string]string{
+ "type": cacheControl.Type,
+ },
+ })
+ }
+ messages = append(messages, tr)
+ }
+ }
+ }
+ }
+ return messages, warnings
+}
+
+func hasVisibleUserContent(content []openaisdk.ChatCompletionContentPartUnionParam) bool {
+ for _, part := range content {
+ if part.OfText != nil || part.OfImageURL != nil || part.OfInputAudio != nil || part.OfFile != nil {
+ return true
+ }
+ }
+ return false
+}
+
+func structToMapJSON(s any) (map[string]any, error) {
+ var result map[string]any
+ jsonBytes, err := json.Marshal(s)
+ if err != nil {
+ return nil, err
+ }
+ err = json.Unmarshal(jsonBytes, &result)
+ if err != nil {
+ return nil, err
+ }
+ return result, nil
+}
diff --git a/internal/fantasy/providers/vercel/provider_options.go b/internal/fantasy/providers/vercel/provider_options.go
new file mode 100644
index 000000000..046ba940d
--- /dev/null
+++ b/internal/fantasy/providers/vercel/provider_options.go
@@ -0,0 +1,191 @@
+// Package vercel provides an implementation of the fantasy AI SDK for Vercel AI Gateway.
+package vercel
+
+import (
+ "encoding/json"
+
+ "charm.land/fantasy"
+)
+
+// Global type identifiers for Vercel-specific provider data.
+const (
+ TypeProviderOptions = Name + ".options"
+ TypeProviderMetadata = Name + ".metadata"
+)
+
+// Register Vercel provider-specific types with the global registry.
+func init() {
+ fantasy.RegisterProviderType(TypeProviderOptions, func(data []byte) (fantasy.ProviderOptionsData, error) {
+ var v ProviderOptions
+ if err := json.Unmarshal(data, &v); err != nil {
+ return nil, err
+ }
+ return &v, nil
+ })
+ fantasy.RegisterProviderType(TypeProviderMetadata, func(data []byte) (fantasy.ProviderOptionsData, error) {
+ var v ProviderMetadata
+ if err := json.Unmarshal(data, &v); err != nil {
+ return nil, err
+ }
+ return &v, nil
+ })
+}
+
+// ReasoningEffort represents the reasoning effort level for Vercel AI Gateway.
+type ReasoningEffort string
+
+const (
+ // ReasoningEffortNone disables reasoning.
+ ReasoningEffortNone ReasoningEffort = "none"
+ // ReasoningEffortMinimal represents minimal reasoning effort (~10% of max_tokens).
+ ReasoningEffortMinimal ReasoningEffort = "minimal"
+ // ReasoningEffortLow represents low reasoning effort (~20% of max_tokens).
+ ReasoningEffortLow ReasoningEffort = "low"
+ // ReasoningEffortMedium represents medium reasoning effort (~50% of max_tokens).
+ ReasoningEffortMedium ReasoningEffort = "medium"
+ // ReasoningEffortHigh represents high reasoning effort (~80% of max_tokens).
+ ReasoningEffortHigh ReasoningEffort = "high"
+ // ReasoningEffortXHigh represents extra high reasoning effort (~95% of max_tokens).
+ ReasoningEffortXHigh ReasoningEffort = "xhigh"
+)
+
+// ReasoningOptions represents reasoning configuration for Vercel AI Gateway.
+type ReasoningOptions struct {
+ // Enabled enables reasoning output. When true, the model will provide its reasoning process.
+ Enabled *bool `json:"enabled,omitempty"`
+ // MaxTokens is the maximum number of tokens to allocate for reasoning.
+ // Cannot be used with Effort.
+ MaxTokens *int64 `json:"max_tokens,omitempty"`
+ // Effort controls reasoning effort level.
+ // Mutually exclusive with MaxTokens.
+ Effort *ReasoningEffort `json:"effort,omitempty"`
+ // Exclude excludes reasoning content from the response but still generates it internally.
+ Exclude *bool `json:"exclude,omitempty"`
+}
+
+// GatewayProviderOptions represents provider routing preferences for Vercel AI Gateway.
+type GatewayProviderOptions struct {
+ // Order is the list of provider slugs to try in order (e.g. ["vertex", "anthropic"]).
+ Order []string `json:"order,omitempty"`
+ // Models is the list of fallback models to try if the primary model fails.
+ Models []string `json:"models,omitempty"`
+}
+
+// BYOKCredential represents a single provider credential for BYOK.
+type BYOKCredential struct {
+ APIKey string `json:"apiKey,omitempty"`
+}
+
+// BYOKOptions represents Bring Your Own Key options for Vercel AI Gateway.
+type BYOKOptions struct {
+ Anthropic map[string][]BYOKCredential `json:"anthropic,omitempty"`
+ OpenAI map[string][]BYOKCredential `json:"openai,omitempty"`
+ Vertex map[string][]BYOKCredential `json:"vertex,omitempty"`
+ Bedrock map[string][]BYOKCredential `json:"bedrock,omitempty"`
+}
+
+// ProviderOptions represents additional options for Vercel AI Gateway provider.
+type ProviderOptions struct {
+ // Reasoning configuration for models that support extended thinking.
+ Reasoning *ReasoningOptions `json:"reasoning,omitempty"`
+ // ProviderOptions for gateway routing preferences.
+ ProviderOptions *GatewayProviderOptions `json:"providerOptions,omitempty"`
+ // BYOK for request-scoped provider credentials.
+ BYOK *BYOKOptions `json:"byok,omitempty"`
+ // User is a unique identifier representing your end-user.
+ User *string `json:"user,omitempty"`
+ // LogitBias modifies the likelihood of specified tokens appearing in the completion.
+ LogitBias map[string]int64 `json:"logit_bias,omitempty"`
+ // LogProbs returns the log probabilities of the tokens.
+ LogProbs *bool `json:"logprobs,omitempty"`
+ // TopLogProbs is the number of top log probabilities to return.
+ TopLogProbs *int64 `json:"top_logprobs,omitempty"`
+ // ParallelToolCalls enables parallel function calling during tool use.
+ ParallelToolCalls *bool `json:"parallel_tool_calls,omitempty"`
+ // ExtraBody for additional request body fields.
+ ExtraBody map[string]any `json:"extra_body,omitempty"`
+}
+
+// Options implements the ProviderOptionsData interface for ProviderOptions.
+func (*ProviderOptions) Options() {}
+
+// MarshalJSON implements custom JSON marshaling with type info for ProviderOptions.
+func (o ProviderOptions) MarshalJSON() ([]byte, error) {
+ type plain ProviderOptions
+ return fantasy.MarshalProviderType(TypeProviderOptions, plain(o))
+}
+
+// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderOptions.
+func (o *ProviderOptions) UnmarshalJSON(data []byte) error {
+ type plain ProviderOptions
+ var p plain
+ if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+ return err
+ }
+ *o = ProviderOptions(p)
+ return nil
+}
+
+// ProviderMetadata represents metadata from Vercel AI Gateway provider.
+type ProviderMetadata struct {
+ Provider string `json:"provider,omitempty"`
+}
+
+// Options implements the ProviderOptionsData interface for ProviderMetadata.
+func (*ProviderMetadata) Options() {}
+
+// MarshalJSON implements custom JSON marshaling with type info for ProviderMetadata.
+func (m ProviderMetadata) MarshalJSON() ([]byte, error) {
+ type plain ProviderMetadata
+ return fantasy.MarshalProviderType(TypeProviderMetadata, plain(m))
+}
+
+// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderMetadata.
+func (m *ProviderMetadata) UnmarshalJSON(data []byte) error {
+ type plain ProviderMetadata
+ var p plain
+ if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
+ return err
+ }
+ *m = ProviderMetadata(p)
+ return nil
+}
+
+// ReasoningDetail represents a reasoning detail from Vercel AI Gateway.
+type ReasoningDetail struct {
+ ID string `json:"id,omitempty"`
+ Type string `json:"type,omitempty"`
+ Text string `json:"text,omitempty"`
+ Data string `json:"data,omitempty"`
+ Format string `json:"format,omitempty"`
+ Summary string `json:"summary,omitempty"`
+ Signature string `json:"signature,omitempty"`
+ Index int `json:"index"`
+}
+
+// ReasoningData represents reasoning data from Vercel AI Gateway response.
+type ReasoningData struct {
+ Reasoning string `json:"reasoning,omitempty"`
+ ReasoningDetails []ReasoningDetail `json:"reasoning_details,omitempty"`
+}
+
+// ReasoningEffortOption creates a pointer to a ReasoningEffort value.
+func ReasoningEffortOption(e ReasoningEffort) *ReasoningEffort {
+ return &e
+}
+
+// NewProviderOptions creates new provider options for Vercel.
+func NewProviderOptions(opts *ProviderOptions) fantasy.ProviderOptions {
+ return fantasy.ProviderOptions{
+ Name: opts,
+ }
+}
+
+// ParseOptions parses provider options from a map for Vercel.
+func ParseOptions(data map[string]any) (*ProviderOptions, error) {
+ var options ProviderOptions
+ if err := fantasy.ParseOptions(data, &options); err != nil {
+ return nil, err
+ }
+ return &options, nil
+}
diff --git a/internal/fantasy/providers/vercel/vercel.go b/internal/fantasy/providers/vercel/vercel.go
new file mode 100644
index 000000000..af87db5eb
--- /dev/null
+++ b/internal/fantasy/providers/vercel/vercel.go
@@ -0,0 +1,114 @@
+// Package vercel provides an implementation of the fantasy AI SDK for Vercel AI Gateway.
+package vercel
+
+import (
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/openai"
+ "github.com/openai/openai-go/v2/option"
+)
+
+type options struct {
+ openaiOptions []openai.Option
+ languageModelOptions []openai.LanguageModelOption
+ sdkOptions []option.RequestOption
+ objectMode fantasy.ObjectMode
+}
+
+const (
+ // DefaultURL is the default URL for the Vercel AI Gateway API.
+ DefaultURL = "https://ai-gateway.vercel.sh/v1"
+ // Name is the name of the Vercel provider.
+ Name = "vercel"
+)
+
+// Option defines a function that configures Vercel provider options.
+type Option = func(*options)
+
+// New creates a new Vercel AI Gateway provider with the given options.
+func New(opts ...Option) (fantasy.Provider, error) {
+ providerOptions := options{
+ openaiOptions: []openai.Option{
+ openai.WithName(Name),
+ openai.WithBaseURL(DefaultURL),
+ },
+ languageModelOptions: []openai.LanguageModelOption{
+ openai.WithLanguageModelPrepareCallFunc(languagePrepareModelCall),
+ openai.WithLanguageModelUsageFunc(languageModelUsage),
+ openai.WithLanguageModelStreamUsageFunc(languageModelStreamUsage),
+ openai.WithLanguageModelStreamExtraFunc(languageModelStreamExtra),
+ openai.WithLanguageModelExtraContentFunc(languageModelExtraContent),
+ openai.WithLanguageModelToPromptFunc(languageModelToPrompt),
+ },
+ objectMode: fantasy.ObjectModeTool, // Default to tool mode for vercel
+ }
+ for _, o := range opts {
+ o(&providerOptions)
+ }
+
+ // Handle object mode: convert unsupported modes to tool
+ // Vercel AI Gateway doesn't support native JSON mode, so we use tool or text
+ objectMode := providerOptions.objectMode
+ if objectMode == fantasy.ObjectModeAuto || objectMode == fantasy.ObjectModeJSON {
+ objectMode = fantasy.ObjectModeTool
+ }
+
+ providerOptions.openaiOptions = append(
+ providerOptions.openaiOptions,
+ openai.WithSDKOptions(providerOptions.sdkOptions...),
+ openai.WithLanguageModelOptions(providerOptions.languageModelOptions...),
+ openai.WithObjectMode(objectMode),
+ )
+ return openai.New(providerOptions.openaiOptions...)
+}
+
+// WithAPIKey sets the API key for the Vercel provider.
+func WithAPIKey(apiKey string) Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithAPIKey(apiKey))
+ }
+}
+
+// WithBaseURL sets the base URL for the Vercel provider.
+func WithBaseURL(url string) Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithBaseURL(url))
+ }
+}
+
+// WithName sets the name for the Vercel provider.
+func WithName(name string) Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithName(name))
+ }
+}
+
+// WithHeaders sets the headers for the Vercel provider.
+func WithHeaders(headers map[string]string) Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithHeaders(headers))
+ }
+}
+
+// WithHTTPClient sets the HTTP client for the Vercel provider.
+func WithHTTPClient(client option.HTTPClient) Option {
+ return func(o *options) {
+ o.openaiOptions = append(o.openaiOptions, openai.WithHTTPClient(client))
+ }
+}
+
+// WithSDKOptions sets the SDK options for the Vercel provider.
+func WithSDKOptions(opts ...option.RequestOption) Option {
+ return func(o *options) {
+ o.sdkOptions = append(o.sdkOptions, opts...)
+ }
+}
+
+// WithObjectMode sets the object generation mode for the Vercel provider.
+// Supported modes: ObjectModeTool, ObjectModeText.
+// ObjectModeAuto and ObjectModeJSON are automatically converted to ObjectModeTool
+// since Vercel AI Gateway doesn't support native JSON mode.
+func WithObjectMode(om fantasy.ObjectMode) Option {
+ return func(o *options) {
+ o.objectMode = om
+ }
+}
diff --git a/internal/fantasy/providertests/.env.sample b/internal/fantasy/providertests/.env.sample
new file mode 100644
index 000000000..af90c7f05
--- /dev/null
+++ b/internal/fantasy/providertests/.env.sample
@@ -0,0 +1,13 @@
+FANTASY_ANTHROPIC_API_KEY=
+FANTASY_AZURE_API_KEY=
+FANTASY_AZURE_BASE_URL=
+FANTASY_BEDROCK_API_KEY=
+FANTASY_GEMINI_API_KEY=
+FANTASY_GROQ_API_KEY=
+FANTASY_HUGGINGFACE_API_KEY=
+FANTASY_OPENAI_API_KEY=
+FANTASY_OPENROUTER_API_KEY=
+FANTASY_VERTEX_LOCATION=us-east5
+FANTASY_VERTEX_PROJECT=fantasy-playground-472418
+FANTASY_XAI_API_KEY=
+FANTASY_ZAI_API_KEY=
diff --git a/internal/fantasy/providertests/anthropic_test.go b/internal/fantasy/providertests/anthropic_test.go
new file mode 100644
index 000000000..3987ea03f
--- /dev/null
+++ b/internal/fantasy/providertests/anthropic_test.go
@@ -0,0 +1,157 @@
+package providertests
+
+import (
+ "context"
+ "net/http"
+ "os"
+ "testing"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/anthropic"
+ "charm.land/x/vcr"
+ "github.com/stretchr/testify/require"
+)
+
+var anthropicTestModels = []testModel{
+ {"claude-sonnet-4", "claude-sonnet-4-20250514", true},
+}
+
+func TestAnthropicCommon(t *testing.T) {
+ var pairs []builderPair
+ for _, m := range anthropicTestModels {
+ pairs = append(pairs, builderPair{m.name, anthropicBuilder(m.model), nil, nil})
+ }
+ testCommon(t, pairs)
+}
+
+func addAnthropicCaching(ctx context.Context, options fantasy.PrepareStepFunctionOptions) (context.Context, fantasy.PrepareStepResult, error) {
+ prepared := fantasy.PrepareStepResult{}
+ prepared.Messages = options.Messages
+
+ for i := range prepared.Messages {
+ prepared.Messages[i].ProviderOptions = nil
+ }
+ providerOption := fantasy.ProviderOptions{
+ anthropic.Name: &anthropic.ProviderCacheControlOptions{
+ CacheControl: anthropic.CacheControl{Type: "ephemeral"},
+ },
+ }
+
+ lastSystemRoleInx := 0
+ systemMessageUpdated := false
+ for i, msg := range prepared.Messages {
+ // only add cache control to the last message
+ if msg.Role == fantasy.MessageRoleSystem {
+ lastSystemRoleInx = i
+ } else if !systemMessageUpdated {
+ prepared.Messages[lastSystemRoleInx].ProviderOptions = providerOption
+ systemMessageUpdated = true
+ }
+ // than add cache control to the last 2 messages
+ if i > len(prepared.Messages)-3 {
+ prepared.Messages[i].ProviderOptions = providerOption
+ }
+ }
+ return ctx, prepared, nil
+}
+
+func TestAnthropicCommonWithCacheControl(t *testing.T) {
+ var pairs []builderPair
+ for _, m := range anthropicTestModels {
+ pairs = append(pairs, builderPair{m.name, anthropicBuilder(m.model), nil, addAnthropicCaching})
+ }
+ testCommon(t, pairs)
+}
+
+func TestAnthropicThinking(t *testing.T) {
+ opts := fantasy.ProviderOptions{
+ anthropic.Name: &anthropic.ProviderOptions{
+ Thinking: &anthropic.ThinkingProviderOption{
+ BudgetTokens: 4000,
+ },
+ },
+ }
+ var pairs []builderPair
+ for _, m := range anthropicTestModels {
+ if !m.reasoning {
+ continue
+ }
+ pairs = append(pairs, builderPair{m.name, anthropicBuilder(m.model), opts, nil})
+ }
+ testThinking(t, pairs, testAnthropicThinking)
+}
+
+func TestAnthropicThinkingWithCacheControl(t *testing.T) {
+ opts := fantasy.ProviderOptions{
+ anthropic.Name: &anthropic.ProviderOptions{
+ Thinking: &anthropic.ThinkingProviderOption{
+ BudgetTokens: 4000,
+ },
+ },
+ }
+ var pairs []builderPair
+ for _, m := range anthropicTestModels {
+ if !m.reasoning {
+ continue
+ }
+ pairs = append(pairs, builderPair{m.name, anthropicBuilder(m.model), opts, addAnthropicCaching})
+ }
+ testThinking(t, pairs, testAnthropicThinking)
+}
+
+func TestAnthropicObjectGeneration(t *testing.T) {
+ var pairs []builderPair
+ for _, m := range anthropicTestModels {
+ pairs = append(pairs, builderPair{m.name, anthropicBuilder(m.model), nil, nil})
+ }
+ testObjectGeneration(t, pairs)
+}
+
+func testAnthropicThinking(t *testing.T, result *fantasy.AgentResult) {
+ reasoningContentCount := 0
+ signaturesCount := 0
+ // Test if we got the signature
+ for _, step := range result.Steps {
+ for _, msg := range step.Messages {
+ for _, content := range msg.Content {
+ if content.GetType() == fantasy.ContentTypeReasoning {
+ reasoningContentCount += 1
+ reasoningContent, ok := fantasy.AsContentType[fantasy.ReasoningPart](content)
+ if !ok {
+ continue
+ }
+ if len(reasoningContent.ProviderOptions) == 0 {
+ continue
+ }
+
+ anthropicReasoningMetadata, ok := reasoningContent.ProviderOptions[anthropic.Name]
+ if !ok {
+ continue
+ }
+ if reasoningContent.Text != "" {
+ if typed, ok := anthropicReasoningMetadata.(*anthropic.ReasoningOptionMetadata); ok {
+ require.NotEmpty(t, typed.Signature)
+ signaturesCount += 1
+ }
+ }
+ }
+ }
+ }
+ }
+ require.Greater(t, reasoningContentCount, 0)
+ require.Greater(t, signaturesCount, 0)
+ require.Equal(t, reasoningContentCount, signaturesCount)
+}
+
+func anthropicBuilder(model string) builderFunc {
+ return func(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := anthropic.New(
+ anthropic.WithAPIKey(os.Getenv("FANTASY_ANTHROPIC_API_KEY")),
+ anthropic.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), model)
+ }
+}
diff --git a/internal/fantasy/providertests/azure_responses_test.go b/internal/fantasy/providertests/azure_responses_test.go
new file mode 100644
index 000000000..8b3945ba4
--- /dev/null
+++ b/internal/fantasy/providertests/azure_responses_test.go
@@ -0,0 +1,98 @@
+package providertests
+
+import (
+ "cmp"
+ "net/http"
+ "os"
+ "testing"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/azure"
+ "charm.land/fantasy/providers/openai"
+ "charm.land/x/vcr"
+ "github.com/stretchr/testify/require"
+)
+
+func TestAzureResponsesCommon(t *testing.T) {
+ var pairs []builderPair
+ models := []testModel{
+ {"azure-gpt-5-mini", "gpt-5-mini", true},
+ {"azure-o4-mini", "o4-mini", true},
+ }
+ for _, m := range models {
+ pairs = append(pairs, builderPair{m.name, azureReasoningBuilder(m.model), nil, nil})
+ }
+ testCommon(t, pairs)
+}
+
+func azureReasoningBuilder(model string) builderFunc {
+ return func(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := azure.New(
+ azure.WithBaseURL(cmp.Or(os.Getenv("FANTASY_AZURE_BASE_URL"), defaultBaseURL)),
+ azure.WithAPIKey(cmp.Or(os.Getenv("FANTASY_AZURE_API_KEY"), "(missing)")),
+ azure.WithHTTPClient(&http.Client{Transport: r}),
+ azure.WithUseResponsesAPI(),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), model)
+ }
+}
+
+func TestAzureResponsesWithSummaryThinking(t *testing.T) {
+ opts := fantasy.ProviderOptions{
+ openai.Name: &openai.ResponsesProviderOptions{
+ Include: []openai.IncludeType{
+ openai.IncludeReasoningEncryptedContent,
+ },
+ ReasoningEffort: openai.ReasoningEffortOption(openai.ReasoningEffortHigh),
+ ReasoningSummary: fantasy.Opt("auto"),
+ },
+ }
+ var pairs []builderPair
+ models := []testModel{
+ {"azure-gpt-5-mini", "gpt-5-mini", true},
+ }
+ for _, m := range models {
+ if !m.reasoning {
+ continue
+ }
+ pairs = append(pairs, builderPair{m.name, azureReasoningBuilder(m.model), opts, nil})
+ }
+ testThinking(t, pairs, testAzureResponsesThinkingWithSummaryThinking)
+}
+
+func testAzureResponsesThinkingWithSummaryThinking(t *testing.T, result *fantasy.AgentResult) {
+ reasoningContentCount := 0
+ encryptedData := 0
+ // Test if we got the signature
+ for _, step := range result.Steps {
+ for _, msg := range step.Messages {
+ for _, content := range msg.Content {
+ if content.GetType() == fantasy.ContentTypeReasoning {
+ reasoningContentCount += 1
+ reasoningContent, ok := fantasy.AsContentType[fantasy.ReasoningPart](content)
+ if !ok {
+ continue
+ }
+ if len(reasoningContent.ProviderOptions) == 0 {
+ continue
+ }
+
+ openaiReasoningMetadata, ok := reasoningContent.ProviderOptions[openai.Name]
+ if !ok {
+ continue
+ }
+ if typed, ok := openaiReasoningMetadata.(*openai.ResponsesReasoningMetadata); ok {
+ require.NotEmpty(t, typed.EncryptedContent)
+ encryptedData += 1
+ }
+ }
+ }
+ }
+ }
+ require.Greater(t, reasoningContentCount, 0)
+ require.Greater(t, encryptedData, 0)
+ require.Equal(t, reasoningContentCount, encryptedData)
+}
diff --git a/internal/fantasy/providertests/azure_test.go b/internal/fantasy/providertests/azure_test.go
new file mode 100644
index 000000000..198b8dc1c
--- /dev/null
+++ b/internal/fantasy/providertests/azure_test.go
@@ -0,0 +1,76 @@
+package providertests
+
+import (
+ "cmp"
+ "net/http"
+ "os"
+ "testing"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/azure"
+ "charm.land/fantasy/providers/openai"
+ "charm.land/x/vcr"
+ "github.com/stretchr/testify/require"
+)
+
+const defaultBaseURL = "https://fantasy-playground-resource.openai.azure.com"
+
+func TestAzureCommon(t *testing.T) {
+ testCommon(t, []builderPair{
+ {"azure-o4-mini", builderAzureO4Mini, nil, nil},
+ {"azure-gpt-5-mini", builderAzureGpt5Mini, nil, nil},
+ {"azure-grok-3-mini", builderAzureGrok3Mini, nil, nil},
+ })
+}
+
+func TestAzureThinking(t *testing.T) {
+ opts := fantasy.ProviderOptions{
+ openai.Name: &openai.ProviderOptions{
+ ReasoningEffort: openai.ReasoningEffortOption(openai.ReasoningEffortHigh),
+ },
+ }
+ testThinking(t, []builderPair{
+ {"azure-gpt-5-mini", builderAzureGpt5Mini, opts, nil},
+ {"azure-grok-3-mini", builderAzureGrok3Mini, opts, nil},
+ }, testAzureThinking)
+}
+
+func testAzureThinking(t *testing.T, result *fantasy.AgentResult) {
+ require.Greater(t, result.Response.Usage.ReasoningTokens, int64(0), "expected reasoning tokens, got none")
+}
+
+func builderAzureO4Mini(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := azure.New(
+ azure.WithBaseURL(cmp.Or(os.Getenv("FANTASY_AZURE_BASE_URL"), defaultBaseURL)),
+ azure.WithAPIKey(cmp.Or(os.Getenv("FANTASY_AZURE_API_KEY"), "(missing)")),
+ azure.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), "o4-mini")
+}
+
+func builderAzureGpt5Mini(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := azure.New(
+ azure.WithBaseURL(cmp.Or(os.Getenv("FANTASY_AZURE_BASE_URL"), defaultBaseURL)),
+ azure.WithAPIKey(cmp.Or(os.Getenv("FANTASY_AZURE_API_KEY"), "(missing)")),
+ azure.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), "gpt-5-mini")
+}
+
+func builderAzureGrok3Mini(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := azure.New(
+ azure.WithBaseURL(cmp.Or(os.Getenv("FANTASY_AZURE_BASE_URL"), defaultBaseURL)),
+ azure.WithAPIKey(cmp.Or(os.Getenv("FANTASY_AZURE_API_KEY"), "(missing)")),
+ azure.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), "grok-3-mini")
+}
diff --git a/internal/fantasy/providertests/bedrock_test.go b/internal/fantasy/providertests/bedrock_test.go
new file mode 100644
index 000000000..da591ade1
--- /dev/null
+++ b/internal/fantasy/providertests/bedrock_test.go
@@ -0,0 +1,68 @@
+package providertests
+
+import (
+ "net/http"
+ "os"
+ "testing"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/bedrock"
+ "charm.land/x/vcr"
+)
+
+func TestBedrockCommon(t *testing.T) {
+ testCommon(t, []builderPair{
+ {"bedrock-anthropic-claude-3-sonnet", builderBedrockClaude3Sonnet, nil, nil},
+ {"bedrock-anthropic-claude-3-opus", builderBedrockClaude3Opus, nil, nil},
+ {"bedrock-anthropic-claude-3-haiku", builderBedrockClaude3Haiku, nil, nil},
+ })
+}
+
+func TestBedrockBasicAuth(t *testing.T) {
+ testSimple(t, builderPair{"bedrock-anthropic-claude-3-sonnet", buildersBedrockBasicAuth, nil, nil})
+}
+
+func builderBedrockClaude3Sonnet(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := bedrock.New(
+ bedrock.WithHTTPClient(&http.Client{Transport: r}),
+ bedrock.WithSkipAuth(!r.IsRecording()),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), "anthropic.claude-3-sonnet-20240229-v1:0")
+}
+
+func builderBedrockClaude3Opus(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := bedrock.New(
+ bedrock.WithHTTPClient(&http.Client{Transport: r}),
+ bedrock.WithSkipAuth(!r.IsRecording()),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), "anthropic.claude-3-opus-20240229-v1:0")
+}
+
+func builderBedrockClaude3Haiku(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := bedrock.New(
+ bedrock.WithHTTPClient(&http.Client{Transport: r}),
+ bedrock.WithSkipAuth(!r.IsRecording()),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), "anthropic.claude-3-haiku-20240307-v1:0")
+}
+
+func buildersBedrockBasicAuth(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := bedrock.New(
+ bedrock.WithHTTPClient(&http.Client{Transport: r}),
+ bedrock.WithAPIKey(os.Getenv("FANTASY_BEDROCK_API_KEY")),
+ bedrock.WithSkipAuth(true),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), "anthropic.claude-3-sonnet-20240229-v1:0")
+}
diff --git a/internal/fantasy/providertests/common_test.go b/internal/fantasy/providertests/common_test.go
new file mode 100644
index 000000000..e5f9c1c0e
--- /dev/null
+++ b/internal/fantasy/providertests/common_test.go
@@ -0,0 +1,361 @@
+package providertests
+
+import (
+ "context"
+ "os"
+ "strconv"
+ "strings"
+ "testing"
+
+ "charm.land/fantasy"
+ "charm.land/x/vcr"
+ "github.com/joho/godotenv"
+ "github.com/stretchr/testify/require"
+)
+
+func init() {
+ if _, err := os.Stat(".env"); err == nil {
+ godotenv.Load(".env")
+ } else {
+ godotenv.Load(".env.sample")
+ }
+}
+
+type testModel struct {
+ name string
+ model string
+ reasoning bool
+}
+
+type builderFunc func(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error)
+
+type builderPair struct {
+ name string
+ builder builderFunc
+ providerOptions fantasy.ProviderOptions
+ prepareStep fantasy.PrepareStepFunction
+}
+
+func testCommon(t *testing.T, pairs []builderPair) {
+ for _, pair := range pairs {
+ t.Run(pair.name, func(t *testing.T) {
+ testSimple(t, pair)
+ testTool(t, pair)
+ testMultiTool(t, pair)
+ })
+ }
+}
+
+func testSimple(t *testing.T, pair builderPair) {
+ checkResult := func(t *testing.T, result *fantasy.AgentResult) {
+ options := []string{"Oi", "oi", "OlĆ”", "olĆ”"}
+ got := result.Response.Content.Text()
+ require.True(t, containsAny(got, options...), "unexpected response: got %q, want any of: %q", got, options)
+ }
+
+ t.Run("simple", func(t *testing.T) {
+ r := vcr.NewRecorder(t)
+
+ languageModel, err := pair.builder(t, r)
+ require.NoError(t, err, "failed to build language model")
+
+ agent := fantasy.NewAgent(
+ languageModel,
+ fantasy.WithSystemPrompt("You are a helpful assistant"),
+ )
+ result, err := agent.Generate(t.Context(), fantasy.AgentCall{
+ Prompt: "Say hi in Portuguese",
+ ProviderOptions: pair.providerOptions,
+ MaxOutputTokens: fantasy.Opt(int64(4000)),
+ PrepareStep: pair.prepareStep,
+ })
+ require.NoError(t, err, "failed to generate")
+ checkResult(t, result)
+ })
+ t.Run("simple streaming", func(t *testing.T) {
+ r := vcr.NewRecorder(t)
+
+ languageModel, err := pair.builder(t, r)
+ require.NoError(t, err, "failed to build language model")
+
+ agent := fantasy.NewAgent(
+ languageModel,
+ fantasy.WithSystemPrompt("You are a helpful assistant"),
+ )
+ result, err := agent.Stream(t.Context(), fantasy.AgentStreamCall{
+ Prompt: "Say hi in Portuguese",
+ ProviderOptions: pair.providerOptions,
+ MaxOutputTokens: fantasy.Opt(int64(4000)),
+ PrepareStep: pair.prepareStep,
+ })
+ require.NoError(t, err, "failed to generate")
+ checkResult(t, result)
+ })
+}
+
+func testTool(t *testing.T, pair builderPair) {
+ type WeatherInput struct {
+ Location string `json:"location" description:"the city"`
+ }
+
+ weatherTool := fantasy.NewAgentTool(
+ "weather",
+ "Get weather information for a location",
+ func(ctx context.Context, input WeatherInput, _ fantasy.ToolCall) (fantasy.ToolResponse, error) {
+ return fantasy.NewTextResponse("40 C"), nil
+ },
+ )
+ checkResult := func(t *testing.T, result *fantasy.AgentResult) {
+ require.GreaterOrEqual(t, len(result.Steps), 2)
+
+ var toolCalls []fantasy.ToolCallContent
+ for _, content := range result.Steps[0].Content {
+ if content.GetType() == fantasy.ContentTypeToolCall {
+ toolCalls = append(toolCalls, content.(fantasy.ToolCallContent))
+ }
+ }
+ for _, tc := range toolCalls {
+ require.False(t, tc.Invalid)
+ }
+ require.Len(t, toolCalls, 1)
+ require.Equal(t, toolCalls[0].ToolName, "weather")
+
+ want1 := "Florence"
+ want2 := "40"
+ got := result.Response.Content.Text()
+ require.True(t, strings.Contains(got, want1) && strings.Contains(got, want2), "unexpected response: got %q, want %q %q", got, want1, want2)
+ }
+
+ t.Run("tool", func(t *testing.T) {
+ r := vcr.NewRecorder(t)
+
+ languageModel, err := pair.builder(t, r)
+ require.NoError(t, err, "failed to build language model")
+
+ agent := fantasy.NewAgent(
+ languageModel,
+ fantasy.WithSystemPrompt("You are a helpful assistant"),
+ fantasy.WithTools(weatherTool),
+ )
+ result, err := agent.Generate(t.Context(), fantasy.AgentCall{
+ Prompt: "What's the weather in Florence,Italy?",
+ ProviderOptions: pair.providerOptions,
+ MaxOutputTokens: fantasy.Opt(int64(4000)),
+ PrepareStep: pair.prepareStep,
+ })
+ require.NoError(t, err, "failed to generate")
+ checkResult(t, result)
+ })
+ t.Run("tool streaming", func(t *testing.T) {
+ r := vcr.NewRecorder(t)
+
+ languageModel, err := pair.builder(t, r)
+ require.NoError(t, err, "failed to build language model")
+
+ agent := fantasy.NewAgent(
+ languageModel,
+ fantasy.WithSystemPrompt("You are a helpful assistant"),
+ fantasy.WithTools(weatherTool),
+ )
+ result, err := agent.Stream(t.Context(), fantasy.AgentStreamCall{
+ Prompt: "What's the weather in Florence,Italy?",
+ ProviderOptions: pair.providerOptions,
+ MaxOutputTokens: fantasy.Opt(int64(4000)),
+ PrepareStep: pair.prepareStep,
+ })
+ require.NoError(t, err, "failed to generate")
+ checkResult(t, result)
+ })
+}
+
+func testMultiTool(t *testing.T, pair builderPair) {
+ // Apparently, Azure and Vertex+Anthropic do not support multi-tools calls at all?
+ if strings.Contains(pair.name, "azure") {
+ t.Skip("skipping multi-tool tests for azure as it does not support parallel multi-tool calls")
+ }
+ if strings.Contains(pair.name, "vertex") && strings.Contains(pair.name, "claude") {
+ t.Skip("skipping multi-tool tests for vertex claude as it does not support parallel multi-tool calls")
+ }
+ if strings.Contains(pair.name, "bedrock") && strings.Contains(pair.name, "claude") {
+ t.Skip("skipping multi-tool tests for bedrock claude as it does not support parallel multi-tool calls")
+ }
+ if strings.Contains(pair.name, "openai") && strings.Contains(pair.name, "o4-mini") {
+ t.Skip("skipping multi-tool tests for openai o4-mini it for some reason is not doing parallel tool calls even if asked")
+ }
+ if strings.Contains(pair.name, "llama-cpp") && strings.Contains(pair.name, "gpt-oss") {
+ t.Skip("skipping multi-tool tests for llama-cpp gpt-oss as it does not support parallel multi-tool calls")
+ }
+
+ type CalculatorInput struct {
+ A int `json:"a" description:"first number"`
+ B int `json:"b" description:"second number"`
+ }
+
+ addTool := fantasy.NewAgentTool(
+ "add",
+ "Add two numbers",
+ func(ctx context.Context, input CalculatorInput, _ fantasy.ToolCall) (fantasy.ToolResponse, error) {
+ result := input.A + input.B
+ return fantasy.NewTextResponse(strings.TrimSpace(strconv.Itoa(result))), nil
+ },
+ )
+ multiplyTool := fantasy.NewAgentTool(
+ "multiply",
+ "Multiply two numbers",
+ func(ctx context.Context, input CalculatorInput, _ fantasy.ToolCall) (fantasy.ToolResponse, error) {
+ result := input.A * input.B
+ return fantasy.NewTextResponse(strings.TrimSpace(strconv.Itoa(result))), nil
+ },
+ )
+ checkResult := func(t *testing.T, result *fantasy.AgentResult) {
+ require.Len(t, result.Steps, 2)
+
+ var toolCalls []fantasy.ToolCallContent
+ for _, content := range result.Steps[0].Content {
+ if content.GetType() == fantasy.ContentTypeToolCall {
+ toolCalls = append(toolCalls, content.(fantasy.ToolCallContent))
+ }
+ }
+ for _, tc := range toolCalls {
+ require.False(t, tc.Invalid)
+ }
+ require.Len(t, toolCalls, 2)
+
+ finalText := result.Response.Content.Text()
+ require.Contains(t, finalText, "5", "expected response to contain '5', got: %q", finalText)
+ require.Contains(t, finalText, "6", "expected response to contain '6', got: %q", finalText)
+ }
+
+ t.Run("multi tool", func(t *testing.T) {
+ r := vcr.NewRecorder(t)
+
+ languageModel, err := pair.builder(t, r)
+ require.NoError(t, err, "failed to build language model")
+
+ agent := fantasy.NewAgent(
+ languageModel,
+ fantasy.WithSystemPrompt("You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS."),
+ fantasy.WithTools(addTool),
+ fantasy.WithTools(multiplyTool),
+ )
+ result, err := agent.Generate(t.Context(), fantasy.AgentCall{
+ Prompt: "Add and multiply the number 2 and 3",
+ ProviderOptions: pair.providerOptions,
+ MaxOutputTokens: fantasy.Opt(int64(4000)),
+ PrepareStep: pair.prepareStep,
+ })
+ require.NoError(t, err, "failed to generate")
+ checkResult(t, result)
+ })
+ t.Run("multi tool streaming", func(t *testing.T) {
+ r := vcr.NewRecorder(t)
+
+ languageModel, err := pair.builder(t, r)
+ require.NoError(t, err, "failed to build language model")
+
+ agent := fantasy.NewAgent(
+ languageModel,
+ fantasy.WithSystemPrompt("You are a helpful assistant. Always use both add and multiply at the same time."),
+ fantasy.WithTools(addTool),
+ fantasy.WithTools(multiplyTool),
+ )
+ result, err := agent.Stream(t.Context(), fantasy.AgentStreamCall{
+ Prompt: "Add and multiply the number 2 and 3",
+ ProviderOptions: pair.providerOptions,
+ MaxOutputTokens: fantasy.Opt(int64(4000)),
+ PrepareStep: pair.prepareStep,
+ })
+ require.NoError(t, err, "failed to generate")
+ checkResult(t, result)
+ })
+}
+
+func testThinking(t *testing.T, pairs []builderPair, thinkChecks func(*testing.T, *fantasy.AgentResult)) {
+ for _, pair := range pairs {
+ t.Run(pair.name, func(t *testing.T) {
+ t.Run("thinking", func(t *testing.T) {
+ r := vcr.NewRecorder(t)
+
+ languageModel, err := pair.builder(t, r)
+ require.NoError(t, err, "failed to build language model")
+
+ type WeatherInput struct {
+ Location string `json:"location" description:"the city"`
+ }
+
+ weatherTool := fantasy.NewAgentTool(
+ "weather",
+ "Get weather information for a location",
+ func(ctx context.Context, input WeatherInput, _ fantasy.ToolCall) (fantasy.ToolResponse, error) {
+ return fantasy.NewTextResponse("40 C"), nil
+ },
+ )
+
+ agent := fantasy.NewAgent(
+ languageModel,
+ fantasy.WithSystemPrompt("You are a helpful assistant"),
+ fantasy.WithTools(weatherTool),
+ )
+ result, err := agent.Generate(t.Context(), fantasy.AgentCall{
+ Prompt: "What's the weather in Florence, Italy?",
+ ProviderOptions: pair.providerOptions,
+ PrepareStep: pair.prepareStep,
+ })
+ require.NoError(t, err, "failed to generate")
+
+ want1 := "Florence"
+ want2 := "40"
+ got := result.Response.Content.Text()
+ require.True(t, strings.Contains(got, want1) && strings.Contains(got, want2), "unexpected response: got %q, want %q %q", got, want1, want2)
+
+ thinkChecks(t, result)
+ })
+ t.Run("thinking-streaming", func(t *testing.T) {
+ r := vcr.NewRecorder(t)
+
+ languageModel, err := pair.builder(t, r)
+ require.NoError(t, err, "failed to build language model")
+
+ type WeatherInput struct {
+ Location string `json:"location" description:"the city"`
+ }
+
+ weatherTool := fantasy.NewAgentTool(
+ "weather",
+ "Get weather information for a location",
+ func(ctx context.Context, input WeatherInput, _ fantasy.ToolCall) (fantasy.ToolResponse, error) {
+ return fantasy.NewTextResponse("40 C"), nil
+ },
+ )
+
+ agent := fantasy.NewAgent(
+ languageModel,
+ fantasy.WithSystemPrompt("You are a helpful assistant"),
+ fantasy.WithTools(weatherTool),
+ )
+ result, err := agent.Stream(t.Context(), fantasy.AgentStreamCall{
+ Prompt: "What's the weather in Florence, Italy?",
+ ProviderOptions: pair.providerOptions,
+ PrepareStep: pair.prepareStep,
+ })
+ require.NoError(t, err, "failed to generate")
+
+ want1 := "Florence"
+ want2 := "40"
+ got := result.Response.Content.Text()
+ require.True(t, strings.Contains(got, want1) && strings.Contains(got, want2), "unexpected response: got %q, want %q %q", got, want1, want2)
+
+ thinkChecks(t, result)
+ })
+ })
+ }
+}
+
+func containsAny(s string, subs ...string) bool {
+ for _, sub := range subs {
+ if strings.Contains(s, sub) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/internal/fantasy/providertests/google_test.go b/internal/fantasy/providertests/google_test.go
new file mode 100644
index 000000000..c681411ab
--- /dev/null
+++ b/internal/fantasy/providertests/google_test.go
@@ -0,0 +1,125 @@
+package providertests
+
+import (
+ "cmp"
+ "fmt"
+ "net/http"
+ "os"
+ "testing"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/google"
+ "charm.land/x/vcr"
+ "github.com/stretchr/testify/require"
+)
+
+var geminiTestModels = []testModel{
+ {"gemini-3-pro-preview", "gemini-3-pro-preview", true},
+ {"gemini-2.5-flash", "gemini-2.5-flash", true},
+ {"gemini-2.5-pro", "gemini-2.5-pro", true},
+}
+
+var vertexTestModels = []testModel{
+ {"vertex-gemini-2-5-flash", "gemini-2.5-flash", true},
+ {"vertex-gemini-2-5-pro", "gemini-2.5-pro", true},
+ {"vertex-claude-3-7-sonnet", "claude-3-7-sonnet@20250219", true},
+}
+
+func TestGoogleCommon(t *testing.T) {
+ var pairs []builderPair
+ for _, m := range geminiTestModels {
+ pairs = append(pairs, builderPair{m.name, geminiBuilder(m.model), nil, nil})
+ }
+ for _, m := range vertexTestModels {
+ pairs = append(pairs, builderPair{m.name, vertexBuilder(m.model), nil, nil})
+ }
+ testCommon(t, pairs)
+}
+
+func TestGoogleThinking(t *testing.T) {
+ opts := fantasy.ProviderOptions{
+ google.Name: &google.ProviderOptions{
+ ThinkingConfig: &google.ThinkingConfig{
+ ThinkingBudget: fantasy.Opt(int64(100)),
+ IncludeThoughts: fantasy.Opt(true),
+ },
+ },
+ }
+
+ var pairs []builderPair
+ for _, m := range geminiTestModels {
+ if !m.reasoning {
+ continue
+ }
+ pairs = append(pairs, builderPair{m.name, geminiBuilder(m.model), opts, nil})
+ }
+ testThinking(t, pairs, testGoogleThinking)
+}
+
+func TestGoogleObjectGeneration(t *testing.T) {
+ var pairs []builderPair
+ for _, m := range geminiTestModels {
+ pairs = append(pairs, builderPair{m.name, geminiBuilder(m.model), nil, nil})
+ }
+ testObjectGeneration(t, pairs)
+}
+
+func TestGoogleVertexObjectGeneration(t *testing.T) {
+ var pairs []builderPair
+ for _, m := range vertexTestModels {
+ pairs = append(pairs, builderPair{m.name, vertexBuilder(m.model), nil, nil})
+ }
+ testObjectGeneration(t, pairs)
+}
+
+func testGoogleThinking(t *testing.T, result *fantasy.AgentResult) {
+ reasoningContentCount := 0
+ // Test if we got the signature
+ for _, step := range result.Steps {
+ for _, msg := range step.Messages {
+ for _, content := range msg.Content {
+ if content.GetType() == fantasy.ContentTypeReasoning {
+ reasoningContentCount += 1
+ }
+ }
+ }
+ }
+ require.Greater(t, reasoningContentCount, 0)
+}
+
+func generateIDMock() google.ToolCallIDFunc {
+ id := 0
+ return func() string {
+ id++
+ return fmt.Sprintf("%d", id)
+ }
+}
+
+func geminiBuilder(model string) builderFunc {
+ return func(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := google.New(
+ google.WithGeminiAPIKey(cmp.Or(os.Getenv("FANTASY_GEMINI_API_KEY"), "(missing)")),
+ google.WithHTTPClient(&http.Client{Transport: r}),
+ google.WithToolCallIDFunc(generateIDMock()),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), model)
+ }
+}
+
+func vertexBuilder(model string) builderFunc {
+ return func(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := google.New(
+ google.WithVertex(os.Getenv("FANTASY_VERTEX_PROJECT"), os.Getenv("FANTASY_VERTEX_LOCATION")),
+ google.WithHTTPClient(&http.Client{Transport: r}),
+ google.WithSkipAuth(!r.IsRecording()),
+ google.WithToolCallIDFunc(generateIDMock()),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), model)
+ }
+}
diff --git a/internal/fantasy/providertests/image_upload_test.go b/internal/fantasy/providertests/image_upload_test.go
new file mode 100644
index 000000000..cf7fad7ca
--- /dev/null
+++ b/internal/fantasy/providertests/image_upload_test.go
@@ -0,0 +1,146 @@
+package providertests
+
+import (
+ "cmp"
+ "net/http"
+ "os"
+ "testing"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/anthropic"
+ "charm.land/fantasy/providers/google"
+ "charm.land/fantasy/providers/openai"
+ "charm.land/x/vcr"
+ "github.com/stretchr/testify/require"
+)
+
+func anthropicImageBuilder(model string) builderFunc {
+ return func(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := anthropic.New(
+ anthropic.WithAPIKey(cmp.Or(os.Getenv("FANTASY_ANTHROPIC_API_KEY"), "(missing)")),
+ anthropic.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), model)
+ }
+}
+
+func openAIImageBuilder(model string) builderFunc {
+ return func(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := openai.New(
+ openai.WithAPIKey(cmp.Or(os.Getenv("FANTASY_OPENAI_API_KEY"), "(missing)")),
+ openai.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), model)
+ }
+}
+
+func geminiImageBuilder(model string) builderFunc {
+ return func(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := google.New(
+ google.WithGeminiAPIKey(cmp.Or(os.Getenv("FANTASY_GEMINI_API_KEY"), "(missing)")),
+ google.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), model)
+ }
+}
+
+func TestImageUploadAgent(t *testing.T) {
+ pairs := []builderPair{
+ {
+ name: "anthropic-claude-sonnet-4",
+ builder: anthropicImageBuilder("claude-sonnet-4-20250514"),
+ },
+ {
+ name: "openai-gpt-5",
+ builder: openAIImageBuilder("gpt-5"),
+ },
+ {
+ name: "gemini-2.5-pro",
+ builder: geminiImageBuilder("gemini-2.5-pro"),
+ },
+ }
+
+ img, err := os.ReadFile("testdata/wish.png")
+ require.NoError(t, err)
+
+ file := fantasy.FilePart{Filename: "wish.png", Data: img, MediaType: "image/png"}
+
+ for _, pair := range pairs {
+ t.Run(pair.name, func(t *testing.T) {
+ r := vcr.NewRecorder(t)
+
+ lm, err := pair.builder(t, r)
+ require.NoError(t, err)
+
+ agent := fantasy.NewAgent(
+ lm,
+ fantasy.WithSystemPrompt("You are a helpful assistant"),
+ )
+
+ result, err := agent.Generate(t.Context(), fantasy.AgentCall{
+ Prompt: "Describe the image briefly in English.",
+ Files: []fantasy.FilePart{file},
+ ProviderOptions: pair.providerOptions,
+ MaxOutputTokens: fantasy.Opt(int64(4000)),
+ })
+ require.NoError(t, err)
+ got := result.Response.Content.Text()
+ require.NotEmpty(t, got, "expected non-empty description for %s", pair.name)
+ })
+ }
+}
+
+func TestImageUploadAgentStreaming(t *testing.T) {
+ pairs := []builderPair{
+ {
+ name: "anthropic-claude-sonnet-4",
+ builder: anthropicImageBuilder("claude-sonnet-4-20250514"),
+ },
+ {
+ name: "openai-gpt-5",
+ builder: openAIImageBuilder("gpt-5"),
+ },
+ {
+ name: "gemini-2.5-pro",
+ builder: geminiImageBuilder("gemini-2.5-pro"),
+ },
+ }
+
+ img, err := os.ReadFile("testdata/wish.png")
+ require.NoError(t, err)
+
+ file := fantasy.FilePart{Filename: "wish.png", Data: img, MediaType: "image/png"}
+
+ for _, pair := range pairs {
+ t.Run(pair.name+"-stream", func(t *testing.T) {
+ r := vcr.NewRecorder(t)
+
+ lm, err := pair.builder(t, r)
+ require.NoError(t, err)
+
+ agent := fantasy.NewAgent(
+ lm,
+ fantasy.WithSystemPrompt("You are a helpful assistant"),
+ )
+
+ result, err := agent.Stream(t.Context(), fantasy.AgentStreamCall{
+ Prompt: "Describe the image briefly in English.",
+ Files: []fantasy.FilePart{file},
+ ProviderOptions: pair.providerOptions,
+ MaxOutputTokens: fantasy.Opt(int64(4000)),
+ })
+ require.NoError(t, err)
+ got := result.Response.Content.Text()
+ require.NotEmpty(t, got, "expected non-empty description for %s", pair.name)
+ })
+ }
+}
diff --git a/internal/fantasy/providertests/object_test.go b/internal/fantasy/providertests/object_test.go
new file mode 100644
index 000000000..9c91e3318
--- /dev/null
+++ b/internal/fantasy/providertests/object_test.go
@@ -0,0 +1,422 @@
+package providertests
+
+import (
+ "context"
+ "strings"
+ "testing"
+
+ "charm.land/fantasy"
+ "charm.land/x/vcr"
+ "github.com/stretchr/testify/require"
+)
+
+// Object generation tests for providers.
+//
+// These test functions can be used to test structured object generation
+// (GenerateObject and StreamObject) for any provider implementation.
+//
+// Usage example:
+//
+// func TestMyProviderObjectGeneration(t *testing.T) {
+// var pairs []builderPair
+// for _, m := range myTestModels {
+// pairs = append(pairs, builderPair{m.name, myBuilder(m.model), nil, nil})
+// }
+// testObjectGeneration(t, pairs)
+// }
+//
+// The tests cover:
+// - Simple object generation (flat schema with basic types)
+// - Complex object generation (nested objects and arrays)
+// - Streaming object generation (progressive updates)
+// - Object generation with custom repair functions
+
+// testObjectGeneration tests structured object generation for a provider.
+// It includes both non-streaming (GenerateObject) and streaming (StreamObject) tests.
+func testObjectGeneration(t *testing.T, pairs []builderPair) {
+ for _, pair := range pairs {
+ t.Run(pair.name, func(t *testing.T) {
+ testSimpleObject(t, pair)
+ testComplexObject(t, pair)
+ })
+ }
+}
+
+func testSimpleObject(t *testing.T, pair builderPair) {
+ // Define a simple schema for a person object
+ schema := fantasy.Schema{
+ Type: "object",
+ Properties: map[string]*fantasy.Schema{
+ "name": {
+ Type: "string",
+ Description: "The person's name",
+ },
+ "age": {
+ Type: "integer",
+ Description: "The person's age",
+ },
+ "city": {
+ Type: "string",
+ Description: "The city where the person lives",
+ },
+ },
+ Required: []string{"name", "age", "city"},
+ }
+
+ checkResult := func(t *testing.T, obj any, rawText string, usage fantasy.Usage) {
+ require.NotNil(t, obj, "object should not be nil")
+ require.NotEmpty(t, rawText, "raw text should not be empty")
+ require.Greater(t, usage.TotalTokens, int64(0), "usage should be tracked")
+
+ // Validate structure
+ objMap, ok := obj.(map[string]any)
+ require.True(t, ok, "object should be a map")
+ require.Contains(t, objMap, "name")
+ require.Contains(t, objMap, "age")
+ require.Contains(t, objMap, "city")
+
+ // Validate types
+ name, ok := objMap["name"].(string)
+ require.True(t, ok, "name should be a string")
+ require.NotEmpty(t, name, "name should not be empty")
+
+ // Age could be float64 from JSON unmarshaling
+ age, ok := objMap["age"].(float64)
+ require.True(t, ok, "age should be a number")
+ require.Greater(t, age, 0.0, "age should be greater than 0")
+
+ city, ok := objMap["city"].(string)
+ require.True(t, ok, "city should be a string")
+ require.NotEmpty(t, city, "city should not be empty")
+ }
+
+ t.Run("simple object", func(t *testing.T) {
+ r := vcr.NewRecorder(t)
+
+ languageModel, err := pair.builder(t, r)
+ require.NoError(t, err, "failed to build language model")
+
+ prompt := fantasy.Prompt{
+ fantasy.NewUserMessage("Generate information about a person named Alice who is 30 years old and lives in Paris."),
+ }
+
+ response, err := languageModel.GenerateObject(t.Context(), fantasy.ObjectCall{
+ Prompt: prompt,
+ Schema: schema,
+ SchemaName: "Person",
+ SchemaDescription: "A person with name, age, and city",
+ MaxOutputTokens: fantasy.Opt(int64(4000)),
+ ProviderOptions: pair.providerOptions,
+ })
+ require.NoError(t, err, "failed to generate object")
+ require.NotNil(t, response, "response should not be nil")
+ checkResult(t, response.Object, response.RawText, response.Usage)
+ })
+
+ t.Run("simple object streaming", func(t *testing.T) {
+ r := vcr.NewRecorder(t)
+
+ languageModel, err := pair.builder(t, r)
+ require.NoError(t, err, "failed to build language model")
+
+ prompt := fantasy.Prompt{
+ fantasy.NewUserMessage("Generate information about a person named Alice who is 30 years old and lives in Paris."),
+ }
+
+ stream, err := languageModel.StreamObject(t.Context(), fantasy.ObjectCall{
+ Prompt: prompt,
+ Schema: schema,
+ SchemaName: "Person",
+ SchemaDescription: "A person with name, age, and city",
+ MaxOutputTokens: fantasy.Opt(int64(4000)),
+ ProviderOptions: pair.providerOptions,
+ })
+ require.NoError(t, err, "failed to create object stream")
+ require.NotNil(t, stream, "stream should not be nil")
+
+ var lastObject any
+ var rawText string
+ var usage fantasy.Usage
+ var finishReason fantasy.FinishReason
+ objectCount := 0
+
+ for part := range stream {
+ switch part.Type {
+ case fantasy.ObjectStreamPartTypeObject:
+ lastObject = part.Object
+ objectCount++
+ case fantasy.ObjectStreamPartTypeTextDelta:
+ rawText += part.Delta
+ case fantasy.ObjectStreamPartTypeFinish:
+ usage = part.Usage
+ finishReason = part.FinishReason
+ case fantasy.ObjectStreamPartTypeError:
+ t.Fatalf("stream error: %v", part.Error)
+ }
+ }
+
+ require.NotNil(t, lastObject, "should have received at least one object")
+ require.Greater(t, objectCount, 0, "should have received object updates")
+ require.NotEqual(t, fantasy.FinishReasonUnknown, finishReason, "should have a finish reason")
+
+ // Validate object structure without requiring rawText (may be empty in tool-based mode)
+ require.NotNil(t, lastObject, "object should not be nil")
+ require.Greater(t, usage.TotalTokens, int64(0), "usage should be tracked")
+
+ // Validate structure
+ objMap, ok := lastObject.(map[string]any)
+ require.True(t, ok, "object should be a map")
+ require.Contains(t, objMap, "name")
+ require.Contains(t, objMap, "age")
+ require.Contains(t, objMap, "city")
+
+ // Validate types
+ name, ok := objMap["name"].(string)
+ require.True(t, ok, "name should be a string")
+ require.NotEmpty(t, name, "name should not be empty")
+
+ // Age could be float64 from JSON unmarshaling
+ age, ok := objMap["age"].(float64)
+ require.True(t, ok, "age should be a number")
+ require.Greater(t, age, 0.0, "age should be greater than 0")
+
+ city, ok := objMap["city"].(string)
+ require.True(t, ok, "city should be a string")
+ require.NotEmpty(t, city, "city should not be empty")
+ })
+}
+
+func testComplexObject(t *testing.T, pair builderPair) {
+ // Define a more complex schema with nested objects and arrays
+ schema := fantasy.Schema{
+ Type: "object",
+ Properties: map[string]*fantasy.Schema{
+ "title": {
+ Type: "string",
+ Description: "The book title",
+ },
+ "author": {
+ Type: "object",
+ Properties: map[string]*fantasy.Schema{
+ "name": {
+ Type: "string",
+ Description: "Author's name",
+ },
+ "nationality": {
+ Type: "string",
+ Description: "Author's nationality",
+ },
+ },
+ Required: []string{"name", "nationality"},
+ },
+ "genres": {
+ Type: "array",
+ Items: &fantasy.Schema{
+ Type: "string",
+ },
+ Description: "List of genres",
+ },
+ "published_year": {
+ Type: "integer",
+ Description: "Year the book was published",
+ },
+ },
+ Required: []string{"title", "author", "genres", "published_year"},
+ }
+
+ checkResult := func(t *testing.T, obj any, rawText string, usage fantasy.Usage) {
+ require.NotNil(t, obj, "object should not be nil")
+ require.NotEmpty(t, rawText, "raw text should not be empty")
+ require.Greater(t, usage.TotalTokens, int64(0), "usage should be tracked")
+
+ // Validate structure
+ objMap, ok := obj.(map[string]any)
+ require.True(t, ok, "object should be a map")
+ require.Contains(t, objMap, "title")
+ require.Contains(t, objMap, "author")
+ require.Contains(t, objMap, "genres")
+ require.Contains(t, objMap, "published_year")
+
+ // Validate title
+ title, ok := objMap["title"].(string)
+ require.True(t, ok, "title should be a string")
+ require.True(t, strings.Contains(strings.ToLower(title), "rings"), "title should contain 'rings'")
+
+ // Validate nested author object
+ author, ok := objMap["author"].(map[string]any)
+ require.True(t, ok, "author should be an object")
+ require.Contains(t, author, "name")
+ require.Contains(t, author, "nationality")
+
+ // Validate genres array
+ genres, ok := objMap["genres"].([]any)
+ require.True(t, ok, "genres should be an array")
+ require.Greater(t, len(genres), 0, "genres should have at least one item")
+ for _, genre := range genres {
+ _, ok := genre.(string)
+ require.True(t, ok, "each genre should be a string")
+ }
+
+ // Validate published_year
+ year, ok := objMap["published_year"].(float64)
+ require.True(t, ok, "published_year should be a number")
+ require.Greater(t, year, 1900.0, "published_year should be after 1900")
+ }
+
+ t.Run("complex object", func(t *testing.T) {
+ r := vcr.NewRecorder(t)
+
+ languageModel, err := pair.builder(t, r)
+ require.NoError(t, err, "failed to build language model")
+
+ prompt := fantasy.Prompt{
+ fantasy.NewUserMessage("Generate information about 'The Lord of the Rings' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954)."),
+ }
+
+ response, err := languageModel.GenerateObject(t.Context(), fantasy.ObjectCall{
+ Prompt: prompt,
+ Schema: schema,
+ SchemaName: "Book",
+ SchemaDescription: "A book with title, author, genres, and publication year",
+ MaxOutputTokens: fantasy.Opt(int64(4000)),
+ ProviderOptions: pair.providerOptions,
+ })
+ require.NoError(t, err, "failed to generate object")
+ require.NotNil(t, response, "response should not be nil")
+ checkResult(t, response.Object, response.RawText, response.Usage)
+ })
+
+ t.Run("complex object streaming", func(t *testing.T) {
+ r := vcr.NewRecorder(t)
+
+ languageModel, err := pair.builder(t, r)
+ require.NoError(t, err, "failed to build language model")
+
+ prompt := fantasy.Prompt{
+ fantasy.NewUserMessage("Generate information about 'The Lord of the Rings' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954)."),
+ }
+
+ stream, err := languageModel.StreamObject(t.Context(), fantasy.ObjectCall{
+ Prompt: prompt,
+ Schema: schema,
+ SchemaName: "Book",
+ SchemaDescription: "A book with title, author, genres, and publication year",
+ MaxOutputTokens: fantasy.Opt(int64(4000)),
+ ProviderOptions: pair.providerOptions,
+ })
+ require.NoError(t, err, "failed to create object stream")
+ require.NotNil(t, stream, "stream should not be nil")
+
+ var lastObject any
+ var rawText string
+ var usage fantasy.Usage
+ var finishReason fantasy.FinishReason
+ objectCount := 0
+
+ for part := range stream {
+ switch part.Type {
+ case fantasy.ObjectStreamPartTypeObject:
+ lastObject = part.Object
+ objectCount++
+ case fantasy.ObjectStreamPartTypeTextDelta:
+ rawText += part.Delta
+ case fantasy.ObjectStreamPartTypeFinish:
+ usage = part.Usage
+ finishReason = part.FinishReason
+ case fantasy.ObjectStreamPartTypeError:
+ t.Fatalf("stream error: %v", part.Error)
+ }
+ }
+
+ require.NotNil(t, lastObject, "should have received at least one object")
+ require.Greater(t, objectCount, 0, "should have received object updates")
+ require.NotEqual(t, fantasy.FinishReasonUnknown, finishReason, "should have a finish reason")
+
+ // Validate object structure without requiring rawText (may be empty in tool-based mode)
+ require.NotNil(t, lastObject, "object should not be nil")
+ require.Greater(t, usage.TotalTokens, int64(0), "usage should be tracked")
+
+ // Validate structure
+ objMap, ok := lastObject.(map[string]any)
+ require.True(t, ok, "object should be a map")
+ require.Contains(t, objMap, "title")
+ require.Contains(t, objMap, "author")
+ require.Contains(t, objMap, "genres")
+ require.Contains(t, objMap, "published_year")
+
+ // Validate title
+ title, ok := objMap["title"].(string)
+ require.True(t, ok, "title should be a string")
+ require.True(t, strings.Contains(strings.ToLower(title), "rings"), "title should contain 'rings'")
+
+ // Validate nested author object
+ author, ok := objMap["author"].(map[string]any)
+ require.True(t, ok, "author should be an object")
+ require.Contains(t, author, "name")
+ require.Contains(t, author, "nationality")
+
+ // Validate genres array
+ genres, ok := objMap["genres"].([]any)
+ require.True(t, ok, "genres should be an array")
+ require.Greater(t, len(genres), 0, "genres should have at least one item")
+ for _, genre := range genres {
+ _, ok := genre.(string)
+ require.True(t, ok, "each genre should be a string")
+ }
+
+ // Validate published_year
+ year, ok := objMap["published_year"].(float64)
+ require.True(t, ok, "published_year should be a number")
+ require.Greater(t, year, 1900.0, "published_year should be after 1900")
+ })
+}
+
+// testObjectWithRepair tests object generation with custom repair functionality.
+func testObjectWithRepair(t *testing.T, pairs []builderPair) {
+ for _, pair := range pairs {
+ t.Run(pair.name, func(t *testing.T) {
+ t.Run("object with repair", func(t *testing.T) {
+ r := vcr.NewRecorder(t)
+
+ languageModel, err := pair.builder(t, r)
+ require.NoError(t, err, "failed to build language model")
+
+ minVal := 1.0
+ schema := fantasy.Schema{
+ Type: "object",
+ Properties: map[string]*fantasy.Schema{
+ "count": {
+ Type: "integer",
+ Description: "A count that must be positive",
+ Minimum: &minVal,
+ },
+ },
+ Required: []string{"count"},
+ }
+
+ prompt := fantasy.Prompt{
+ fantasy.NewUserMessage("Return a count of 5"),
+ }
+
+ repairFunc := func(ctx context.Context, text string, err error) (string, error) {
+ // Simple repair: if the JSON is malformed, try to fix it
+ // This is a placeholder - real repair would be more sophisticated
+ return text, nil
+ }
+
+ response, err := languageModel.GenerateObject(t.Context(), fantasy.ObjectCall{
+ Prompt: prompt,
+ Schema: schema,
+ SchemaName: "Count",
+ SchemaDescription: "A simple count object",
+ MaxOutputTokens: fantasy.Opt(int64(4000)),
+ RepairText: repairFunc,
+ ProviderOptions: pair.providerOptions,
+ })
+ require.NoError(t, err, "failed to generate object")
+ require.NotNil(t, response, "response should not be nil")
+ require.NotNil(t, response.Object, "object should not be nil")
+ })
+ })
+ }
+}
diff --git a/internal/fantasy/providertests/openai_responses_test.go b/internal/fantasy/providertests/openai_responses_test.go
new file mode 100644
index 000000000..db85f73d4
--- /dev/null
+++ b/internal/fantasy/providertests/openai_responses_test.go
@@ -0,0 +1,96 @@
+package providertests
+
+import (
+ "net/http"
+ "os"
+ "testing"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/openai"
+ "charm.land/x/vcr"
+ "github.com/stretchr/testify/require"
+)
+
+func TestOpenAIResponsesCommon(t *testing.T) {
+ var pairs []builderPair
+ for _, m := range openaiTestModels {
+ pairs = append(pairs, builderPair{m.name, openAIReasoningBuilder(m.model), nil, nil})
+ }
+ testCommon(t, pairs)
+}
+
+func openAIReasoningBuilder(model string) builderFunc {
+ return func(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := openai.New(
+ openai.WithAPIKey(os.Getenv("FANTASY_OPENAI_API_KEY")),
+ openai.WithHTTPClient(&http.Client{Transport: r}),
+ openai.WithUseResponsesAPI(),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), model)
+ }
+}
+
+func TestOpenAIResponsesWithSummaryThinking(t *testing.T) {
+ opts := fantasy.ProviderOptions{
+ openai.Name: &openai.ResponsesProviderOptions{
+ Include: []openai.IncludeType{
+ openai.IncludeReasoningEncryptedContent,
+ },
+ ReasoningEffort: openai.ReasoningEffortOption(openai.ReasoningEffortHigh),
+ ReasoningSummary: fantasy.Opt("auto"),
+ },
+ }
+ var pairs []builderPair
+ for _, m := range openaiTestModels {
+ if !m.reasoning {
+ continue
+ }
+ pairs = append(pairs, builderPair{m.name, openAIReasoningBuilder(m.model), opts, nil})
+ }
+ testThinking(t, pairs, testOpenAIResponsesThinkingWithSummaryThinking)
+}
+
+func TestOpenAIResponsesObjectGeneration(t *testing.T) {
+ var pairs []builderPair
+ for _, m := range openaiTestModels {
+ pairs = append(pairs, builderPair{m.name, openAIReasoningBuilder(m.model), nil, nil})
+ }
+ testObjectGeneration(t, pairs)
+}
+
+func testOpenAIResponsesThinkingWithSummaryThinking(t *testing.T, result *fantasy.AgentResult) {
+ reasoningContentCount := 0
+ encryptedData := 0
+ // Test if we got the signature
+ for _, step := range result.Steps {
+ for _, msg := range step.Messages {
+ for _, content := range msg.Content {
+ if content.GetType() == fantasy.ContentTypeReasoning {
+ reasoningContentCount += 1
+ reasoningContent, ok := fantasy.AsContentType[fantasy.ReasoningPart](content)
+ if !ok {
+ continue
+ }
+ if len(reasoningContent.ProviderOptions) == 0 {
+ continue
+ }
+
+ openaiReasoningMetadata, ok := reasoningContent.ProviderOptions[openai.Name]
+ if !ok {
+ continue
+ }
+ if typed, ok := openaiReasoningMetadata.(*openai.ResponsesReasoningMetadata); ok {
+ require.NotEmpty(t, typed.EncryptedContent)
+ encryptedData += 1
+ }
+ }
+ }
+ }
+ }
+ require.Greater(t, reasoningContentCount, 0)
+ require.Greater(t, encryptedData, 0)
+ require.Equal(t, reasoningContentCount, encryptedData)
+}
diff --git a/internal/fantasy/providertests/openai_test.go b/internal/fantasy/providertests/openai_test.go
new file mode 100644
index 000000000..e232ed999
--- /dev/null
+++ b/internal/fantasy/providertests/openai_test.go
@@ -0,0 +1,47 @@
+package providertests
+
+import (
+ "net/http"
+ "os"
+ "testing"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/openai"
+ "charm.land/x/vcr"
+)
+
+var openaiTestModels = []testModel{
+ {"openai-gpt-4o", "gpt-4o", false},
+ {"openai-gpt-4o-mini", "gpt-4o-mini", false},
+ {"openai-gpt-5", "gpt-5", true},
+ {"openai-o4-mini", "o4-mini", true},
+}
+
+func TestOpenAICommon(t *testing.T) {
+ var pairs []builderPair
+ for _, m := range openaiTestModels {
+ pairs = append(pairs, builderPair{m.name, openAIBuilder(m.model), nil, nil})
+ }
+ testCommon(t, pairs)
+}
+
+func TestOpenAIObjectGeneration(t *testing.T) {
+ var pairs []builderPair
+ for _, m := range openaiTestModels {
+ pairs = append(pairs, builderPair{m.name, openAIBuilder(m.model), nil, nil})
+ }
+ testObjectGeneration(t, pairs)
+}
+
+func openAIBuilder(model string) builderFunc {
+ return func(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := openai.New(
+ openai.WithAPIKey(os.Getenv("FANTASY_OPENAI_API_KEY")),
+ openai.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), model)
+ }
+}
diff --git a/internal/fantasy/providertests/openaicompat_test.go b/internal/fantasy/providertests/openaicompat_test.go
new file mode 100644
index 000000000..c19891345
--- /dev/null
+++ b/internal/fantasy/providertests/openaicompat_test.go
@@ -0,0 +1,142 @@
+package providertests
+
+import (
+ "net/http"
+ "os"
+ "testing"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/openai"
+ "charm.land/fantasy/providers/openaicompat"
+ "charm.land/x/vcr"
+ "github.com/stretchr/testify/require"
+)
+
+func TestOpenAICompatibleCommon(t *testing.T) {
+ testCommon(t, []builderPair{
+ {"xai-grok-4-fast", builderXAIGrok4Fast, nil, nil},
+ {"xai-grok-code-fast", builderXAIGrokCodeFast, nil, nil},
+ {"groq-kimi-k2", builderGroq, nil, nil},
+ {"zai-glm-4.5", builderZAIGLM45, nil, nil},
+ {"huggingface-qwen3-coder", builderHuggingFace, nil, nil},
+ {"llama-cpp-gpt-oss", builderLlamaCppGptOss, nil, nil},
+ })
+}
+
+func TestOpenAICompatObjectGeneration(t *testing.T) {
+ testObjectGeneration(t, []builderPair{
+ {"xai-grok-4-fast", builderXAIGrok4Fast, nil, nil},
+ {"xai-grok-code-fast", builderXAIGrokCodeFast, nil, nil},
+ {"zai-glm-4.5", builderZAIGLM45, nil, nil},
+ })
+}
+
+func TestOpenAICompatibleThinking(t *testing.T) {
+ opts := fantasy.ProviderOptions{
+ openaicompat.Name: &openaicompat.ProviderOptions{
+ ReasoningEffort: openai.ReasoningEffortOption(openai.ReasoningEffortHigh),
+ },
+ }
+ testThinking(t, []builderPair{
+ {"xai-grok-3-mini", builderXAIGrok3Mini, opts, nil},
+ {"zai-glm-4.5", builderZAIGLM45, opts, nil},
+ {"llama-cpp-gpt-oss", builderLlamaCppGptOss, opts, nil},
+ }, testOpenAICompatThinking)
+}
+
+func testOpenAICompatThinking(t *testing.T, result *fantasy.AgentResult) {
+ reasoningContentCount := 0
+ for _, step := range result.Steps {
+ for _, msg := range step.Messages {
+ for _, content := range msg.Content {
+ if content.GetType() == fantasy.ContentTypeReasoning {
+ reasoningContentCount += 1
+ }
+ }
+ }
+ }
+ require.Greater(t, reasoningContentCount, 0, "expected reasoning content, got none")
+}
+
+func builderXAIGrokCodeFast(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := openaicompat.New(
+ openaicompat.WithBaseURL("https://api.x.ai/v1"),
+ openaicompat.WithAPIKey(os.Getenv("FANTASY_XAI_API_KEY")),
+ openaicompat.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), "grok-code-fast-1")
+}
+
+func builderXAIGrok4Fast(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := openaicompat.New(
+ openaicompat.WithBaseURL("https://api.x.ai/v1"),
+ openaicompat.WithAPIKey(os.Getenv("FANTASY_XAI_API_KEY")),
+ openaicompat.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), "grok-4-fast")
+}
+
+func builderXAIGrok3Mini(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := openaicompat.New(
+ openaicompat.WithBaseURL("https://api.x.ai/v1"),
+ openaicompat.WithAPIKey(os.Getenv("FANTASY_XAI_API_KEY")),
+ openaicompat.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), "grok-3-mini")
+}
+
+func builderZAIGLM45(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := openaicompat.New(
+ openaicompat.WithBaseURL("https://api.z.ai/api/coding/paas/v4"),
+ openaicompat.WithAPIKey(os.Getenv("FANTASY_ZAI_API_KEY")),
+ openaicompat.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), "glm-4.5")
+}
+
+func builderGroq(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := openaicompat.New(
+ openaicompat.WithBaseURL("https://api.groq.com/openai/v1"),
+ openaicompat.WithAPIKey(os.Getenv("FANTASY_GROQ_API_KEY")),
+ openaicompat.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), "moonshotai/kimi-k2-instruct-0905")
+}
+
+func builderHuggingFace(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := openaicompat.New(
+ openaicompat.WithBaseURL("https://router.huggingface.co/v1"),
+ openaicompat.WithAPIKey(os.Getenv("FANTASY_HUGGINGFACE_API_KEY")),
+ openaicompat.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), "zai-org/GLM-4.6:cerebras")
+}
+
+func builderLlamaCppGptOss(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := openaicompat.New(
+ openaicompat.WithBaseURL("http://localhost:8080/v1"),
+ openaicompat.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), "openai/gpt-oss-20b")
+}
diff --git a/internal/fantasy/providertests/openrouter_test.go b/internal/fantasy/providertests/openrouter_test.go
new file mode 100644
index 000000000..13f117c1c
--- /dev/null
+++ b/internal/fantasy/providertests/openrouter_test.go
@@ -0,0 +1,129 @@
+package providertests
+
+import (
+ "net/http"
+ "os"
+ "testing"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/anthropic"
+ "charm.land/fantasy/providers/openrouter"
+ "charm.land/x/vcr"
+ "github.com/stretchr/testify/require"
+)
+
+var openrouterTestModels = []testModel{
+ {"kimi-k2", "moonshotai/kimi-k2-0905", false},
+ {"grok-code-fast-1", "x-ai/grok-code-fast-1", true},
+ {"claude-sonnet-4", "anthropic/claude-sonnet-4", true},
+ {"gemini-2.5-flash", "google/gemini-2.5-flash", false},
+ {"deepseek-chat-v3.1-free", "deepseek/deepseek-chat-v3.1:free", false},
+ {"qwen3-235b-a22b-2507", "qwen/qwen3-235b-a22b-2507", false},
+ {"gpt-5", "openai/gpt-5", true},
+ {"gemini-3-pro-preview", "google/gemini-3-pro-preview", true},
+ {"glm-4.5", "z-ai/glm-4.5", false},
+ {"glm-4.6", "z-ai/glm-4.6", true},
+}
+
+func TestOpenRouterCommon(t *testing.T) {
+ var pairs []builderPair
+ for _, m := range openrouterTestModels {
+ pairs = append(pairs, builderPair{m.name, openrouterBuilder(m.model), nil, nil})
+ }
+ testCommon(t, pairs)
+}
+
+func TestOpenRouterCommonWithAnthropicCache(t *testing.T) {
+ testCommon(t, []builderPair{
+ {"claude-sonnet-4", openrouterBuilder("anthropic/claude-sonnet-4"), nil, addAnthropicCaching},
+ })
+}
+
+func TestOpenRouterThinking(t *testing.T) {
+ opts := fantasy.ProviderOptions{
+ openrouter.Name: &openrouter.ProviderOptions{
+ Reasoning: &openrouter.ReasoningOptions{
+ Effort: openrouter.ReasoningEffortOption(openrouter.ReasoningEffortMedium),
+ },
+ },
+ }
+
+ var pairs []builderPair
+ for _, m := range openrouterTestModels {
+ if !m.reasoning {
+ continue
+ }
+ pairs = append(pairs, builderPair{m.name, openrouterBuilder(m.model), opts, nil})
+ }
+ testThinking(t, pairs, testOpenrouterThinking)
+
+ // test anthropic signature
+ testThinking(t, []builderPair{
+ {"claude-sonnet-4-sig", openrouterBuilder("anthropic/claude-sonnet-4"), opts, nil},
+ }, testOpenrouterThinkingWithSignature)
+}
+
+func testOpenrouterThinkingWithSignature(t *testing.T, result *fantasy.AgentResult) {
+ reasoningContentCount := 0
+ signaturesCount := 0
+ // Test if we got the signature
+ for _, step := range result.Steps {
+ for _, msg := range step.Messages {
+ for _, content := range msg.Content {
+ if content.GetType() == fantasy.ContentTypeReasoning {
+ reasoningContentCount += 1
+ reasoningContent, ok := fantasy.AsContentType[fantasy.ReasoningPart](content)
+ if !ok {
+ continue
+ }
+ if len(reasoningContent.ProviderOptions) == 0 {
+ continue
+ }
+
+ anthropicReasoningMetadata, ok := reasoningContent.ProviderOptions[anthropic.Name]
+ if !ok {
+ continue
+ }
+ if reasoningContent.Text != "" {
+ if typed, ok := anthropicReasoningMetadata.(*anthropic.ReasoningOptionMetadata); ok {
+ require.NotEmpty(t, typed.Signature)
+ signaturesCount += 1
+ }
+ }
+ }
+ }
+ }
+ }
+ require.Greater(t, reasoningContentCount, 0)
+ require.Greater(t, signaturesCount, 0)
+ require.Equal(t, reasoningContentCount, signaturesCount)
+ // we also add the anthropic metadata so test that
+ testAnthropicThinking(t, result)
+}
+
+func testOpenrouterThinking(t *testing.T, result *fantasy.AgentResult) {
+ reasoningContentCount := 0
+ for _, step := range result.Steps {
+ for _, msg := range step.Messages {
+ for _, content := range msg.Content {
+ if content.GetType() == fantasy.ContentTypeReasoning {
+ reasoningContentCount += 1
+ }
+ }
+ }
+ }
+ require.Greater(t, reasoningContentCount, 0)
+}
+
+func openrouterBuilder(model string) builderFunc {
+ return func(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := openrouter.New(
+ openrouter.WithAPIKey(os.Getenv("FANTASY_OPENROUTER_API_KEY")),
+ openrouter.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), model)
+ }
+}
diff --git a/internal/fantasy/providertests/provider_registry_test.go b/internal/fantasy/providertests/provider_registry_test.go
new file mode 100644
index 000000000..e798e4894
--- /dev/null
+++ b/internal/fantasy/providertests/provider_registry_test.go
@@ -0,0 +1,421 @@
+package providertests
+
+import (
+ "encoding/json"
+ "testing"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/anthropic"
+ "charm.land/fantasy/providers/google"
+ "charm.land/fantasy/providers/openai"
+ "charm.land/fantasy/providers/openaicompat"
+ "charm.land/fantasy/providers/openrouter"
+ "github.com/stretchr/testify/require"
+)
+
+func TestProviderRegistry_Serialization_OpenAIOptions(t *testing.T) {
+ msg := fantasy.Message{
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "hi"},
+ },
+ ProviderOptions: fantasy.ProviderOptions{
+ openai.Name: &openai.ProviderOptions{User: fantasy.Opt("tester")},
+ },
+ }
+
+ data, err := json.Marshal(msg)
+ require.NoError(t, err)
+
+ var raw struct {
+ ProviderOptions map[string]map[string]any `json:"provider_options"`
+ }
+ require.NoError(t, json.Unmarshal(data, &raw))
+
+ po, ok := raw.ProviderOptions[openai.Name]
+ require.True(t, ok)
+ require.Equal(t, openai.TypeProviderOptions, po["type"]) // no magic strings
+ // ensure inner data has the field we set
+ inner, ok := po["data"].(map[string]any)
+ require.True(t, ok)
+ require.Equal(t, "tester", inner["user"])
+
+ var decoded fantasy.Message
+ require.NoError(t, json.Unmarshal(data, &decoded))
+
+ got, ok := decoded.ProviderOptions[openai.Name]
+ require.True(t, ok)
+ opt, ok := got.(*openai.ProviderOptions)
+ require.True(t, ok)
+ require.NotNil(t, opt.User)
+ require.Equal(t, "tester", *opt.User)
+}
+
+func TestProviderRegistry_Serialization_OpenAIResponses(t *testing.T) {
+ // Use ResponsesProviderOptions in provider options
+ msg := fantasy.Message{
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "hello"},
+ },
+ ProviderOptions: fantasy.ProviderOptions{
+ openai.Name: &openai.ResponsesProviderOptions{
+ PromptCacheKey: fantasy.Opt("cache-key-1"),
+ ParallelToolCalls: fantasy.Opt(true),
+ },
+ },
+ }
+
+ data, err := json.Marshal(msg)
+ require.NoError(t, err)
+
+ // JSON should include the typed wrapper with constant TypeResponsesProviderOptions
+ var raw struct {
+ ProviderOptions map[string]map[string]any `json:"provider_options"`
+ }
+ require.NoError(t, json.Unmarshal(data, &raw))
+
+ po := raw.ProviderOptions[openai.Name]
+ require.Equal(t, openai.TypeResponsesProviderOptions, po["type"]) // no magic strings
+ inner, ok := po["data"].(map[string]any)
+ require.True(t, ok)
+ require.Equal(t, "cache-key-1", inner["prompt_cache_key"])
+ require.Equal(t, true, inner["parallel_tool_calls"])
+
+ // Unmarshal back and assert concrete type
+ var decoded fantasy.Message
+ require.NoError(t, json.Unmarshal(data, &decoded))
+ got := decoded.ProviderOptions[openai.Name]
+ reqOpts, ok := got.(*openai.ResponsesProviderOptions)
+ require.True(t, ok)
+ require.NotNil(t, reqOpts.PromptCacheKey)
+ require.Equal(t, "cache-key-1", *reqOpts.PromptCacheKey)
+ require.NotNil(t, reqOpts.ParallelToolCalls)
+ require.Equal(t, true, *reqOpts.ParallelToolCalls)
+}
+
+func TestProviderRegistry_Serialization_OpenAIResponsesReasoningMetadata(t *testing.T) {
+ resp := fantasy.Response{
+ Content: []fantasy.Content{
+ fantasy.TextContent{
+ Text: "",
+ ProviderMetadata: fantasy.ProviderMetadata{
+ openai.Name: &openai.ResponsesReasoningMetadata{
+ ItemID: "item-123",
+ Summary: []string{"part1", "part2"},
+ },
+ },
+ },
+ },
+ }
+
+ data, err := json.Marshal(resp)
+ require.NoError(t, err)
+
+ // Ensure the provider metadata is wrapped with type using constant
+ var raw struct {
+ Content []struct {
+ Type string `json:"type"`
+ Data map[string]any `json:"data"`
+ } `json:"content"`
+ }
+ require.NoError(t, json.Unmarshal(data, &raw))
+ require.Greater(t, len(raw.Content), 0)
+ tc := raw.Content[0]
+ pm, ok := tc.Data["provider_metadata"].(map[string]any)
+ require.True(t, ok)
+ om, ok := pm[openai.Name].(map[string]any)
+ require.True(t, ok)
+ require.Equal(t, openai.TypeResponsesReasoningMetadata, om["type"]) // no magic strings
+ inner, ok := om["data"].(map[string]any)
+ require.True(t, ok)
+ require.Equal(t, "item-123", inner["item_id"])
+
+ // Unmarshal back
+ var decoded fantasy.Response
+ require.NoError(t, json.Unmarshal(data, &decoded))
+ pmDecoded := decoded.Content[0].(fantasy.TextContent).ProviderMetadata
+ val, ok := pmDecoded[openai.Name]
+ require.True(t, ok)
+ meta, ok := val.(*openai.ResponsesReasoningMetadata)
+ require.True(t, ok)
+ require.Equal(t, "item-123", meta.ItemID)
+ require.Equal(t, []string{"part1", "part2"}, meta.Summary)
+}
+
+func TestProviderRegistry_Serialization_AnthropicOptions(t *testing.T) {
+ sendReasoning := true
+ msg := fantasy.Message{
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "test message"},
+ },
+ ProviderOptions: fantasy.ProviderOptions{
+ anthropic.Name: &anthropic.ProviderOptions{
+ SendReasoning: &sendReasoning,
+ },
+ },
+ }
+
+ data, err := json.Marshal(msg)
+ require.NoError(t, err)
+
+ var decoded fantasy.Message
+ require.NoError(t, json.Unmarshal(data, &decoded))
+
+ got, ok := decoded.ProviderOptions[anthropic.Name]
+ require.True(t, ok)
+ opt, ok := got.(*anthropic.ProviderOptions)
+ require.True(t, ok)
+ require.NotNil(t, opt.SendReasoning)
+ require.Equal(t, true, *opt.SendReasoning)
+}
+
+func TestProviderRegistry_Serialization_GoogleOptions(t *testing.T) {
+ msg := fantasy.Message{
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "test message"},
+ },
+ ProviderOptions: fantasy.ProviderOptions{
+ google.Name: &google.ProviderOptions{
+ CachedContent: "cached-123",
+ Threshold: "BLOCK_ONLY_HIGH",
+ },
+ },
+ }
+
+ data, err := json.Marshal(msg)
+ require.NoError(t, err)
+
+ var decoded fantasy.Message
+ require.NoError(t, json.Unmarshal(data, &decoded))
+
+ got, ok := decoded.ProviderOptions[google.Name]
+ require.True(t, ok)
+ opt, ok := got.(*google.ProviderOptions)
+ require.True(t, ok)
+ require.Equal(t, "cached-123", opt.CachedContent)
+ require.Equal(t, "BLOCK_ONLY_HIGH", opt.Threshold)
+}
+
+func TestProviderRegistry_Serialization_OpenRouterOptions(t *testing.T) {
+ includeUsage := true
+ msg := fantasy.Message{
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "test message"},
+ },
+ ProviderOptions: fantasy.ProviderOptions{
+ openrouter.Name: &openrouter.ProviderOptions{
+ IncludeUsage: &includeUsage,
+ User: fantasy.Opt("test-user"),
+ },
+ },
+ }
+
+ data, err := json.Marshal(msg)
+ require.NoError(t, err)
+
+ var decoded fantasy.Message
+ require.NoError(t, json.Unmarshal(data, &decoded))
+
+ got, ok := decoded.ProviderOptions[openrouter.Name]
+ require.True(t, ok)
+ opt, ok := got.(*openrouter.ProviderOptions)
+ require.True(t, ok)
+ require.NotNil(t, opt.IncludeUsage)
+ require.Equal(t, true, *opt.IncludeUsage)
+ require.NotNil(t, opt.User)
+ require.Equal(t, "test-user", *opt.User)
+}
+
+func TestProviderRegistry_Serialization_OpenAICompatOptions(t *testing.T) {
+ effort := openai.ReasoningEffortHigh
+ msg := fantasy.Message{
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "test message"},
+ },
+ ProviderOptions: fantasy.ProviderOptions{
+ openaicompat.Name: &openaicompat.ProviderOptions{
+ User: fantasy.Opt("test-user"),
+ ReasoningEffort: &effort,
+ },
+ },
+ }
+
+ data, err := json.Marshal(msg)
+ require.NoError(t, err)
+
+ var decoded fantasy.Message
+ require.NoError(t, json.Unmarshal(data, &decoded))
+
+ got, ok := decoded.ProviderOptions[openaicompat.Name]
+ require.True(t, ok)
+ opt, ok := got.(*openaicompat.ProviderOptions)
+ require.True(t, ok)
+ require.NotNil(t, opt.User)
+ require.Equal(t, "test-user", *opt.User)
+ require.NotNil(t, opt.ReasoningEffort)
+ require.Equal(t, openai.ReasoningEffortHigh, *opt.ReasoningEffort)
+}
+
+func TestProviderRegistry_MultiProvider(t *testing.T) {
+ // Test with multiple providers in one message
+ sendReasoning := true
+ msg := fantasy.Message{
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "test"},
+ },
+ ProviderOptions: fantasy.ProviderOptions{
+ openai.Name: &openai.ProviderOptions{User: fantasy.Opt("user1")},
+ anthropic.Name: &anthropic.ProviderOptions{
+ SendReasoning: &sendReasoning,
+ },
+ },
+ }
+
+ data, err := json.Marshal(msg)
+ require.NoError(t, err)
+
+ var decoded fantasy.Message
+ require.NoError(t, json.Unmarshal(data, &decoded))
+
+ // Check OpenAI options
+ openaiOpt, ok := decoded.ProviderOptions[openai.Name]
+ require.True(t, ok)
+ openaiData, ok := openaiOpt.(*openai.ProviderOptions)
+ require.True(t, ok)
+ require.Equal(t, "user1", *openaiData.User)
+
+ // Check Anthropic options
+ anthropicOpt, ok := decoded.ProviderOptions[anthropic.Name]
+ require.True(t, ok)
+ anthropicData, ok := anthropicOpt.(*anthropic.ProviderOptions)
+ require.True(t, ok)
+ require.Equal(t, true, *anthropicData.SendReasoning)
+}
+
+func TestProviderRegistry_ErrorHandling(t *testing.T) {
+ t.Run("unknown provider type", func(t *testing.T) {
+ invalidJSON := `{
+ "role": "user",
+ "content": [{"type": "text", "data": {"text": "hi"}}],
+ "provider_options": {
+ "unknown": {
+ "type": "unknown.provider.type",
+ "data": {}
+ }
+ }
+ }`
+
+ var msg fantasy.Message
+ err := json.Unmarshal([]byte(invalidJSON), &msg)
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "unknown provider data type")
+ })
+
+ t.Run("malformed provider data", func(t *testing.T) {
+ invalidJSON := `{
+ "role": "user",
+ "content": [{"type": "text", "data": {"text": "hi"}}],
+ "provider_options": {
+ "openai": "not-an-object"
+ }
+ }`
+
+ var msg fantasy.Message
+ err := json.Unmarshal([]byte(invalidJSON), &msg)
+ require.Error(t, err)
+ })
+}
+
+func TestProviderRegistry_AllTypesRegistered(t *testing.T) {
+ // Verify all expected provider types are registered
+ // We test that unmarshaling with proper type IDs doesn't fail with "unknown provider data type"
+ tests := []struct {
+ name string
+ providerName string
+ data fantasy.ProviderOptionsData
+ }{
+ {"OpenAI Options", openai.Name, &openai.ProviderOptions{}},
+ {"OpenAI File Options", openai.Name, &openai.ProviderFileOptions{}},
+ {"OpenAI Metadata", openai.Name, &openai.ProviderMetadata{}},
+ {"OpenAI Responses Options", openai.Name, &openai.ResponsesProviderOptions{}},
+ {"Anthropic Options", anthropic.Name, &anthropic.ProviderOptions{}},
+ {"Google Options", google.Name, &google.ProviderOptions{}},
+ {"OpenRouter Options", openrouter.Name, &openrouter.ProviderOptions{}},
+ {"OpenAICompat Options", openaicompat.Name, &openaicompat.ProviderOptions{}},
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ // Create a message with the provider options
+ msg := fantasy.Message{
+ Role: fantasy.MessageRoleUser,
+ Content: []fantasy.MessagePart{
+ fantasy.TextPart{Text: "test"},
+ },
+ ProviderOptions: fantasy.ProviderOptions{
+ tc.providerName: tc.data,
+ },
+ }
+
+ // Marshal and unmarshal
+ data, err := json.Marshal(msg)
+ require.NoError(t, err)
+
+ var decoded fantasy.Message
+ err = json.Unmarshal(data, &decoded)
+ require.NoError(t, err)
+
+ // Verify the provider options exist
+ _, ok := decoded.ProviderOptions[tc.providerName]
+ require.True(t, ok, "Provider options should be present after round-trip")
+ })
+ }
+
+ // Test metadata types separately as they go in different field
+ metadataTests := []struct {
+ name string
+ providerName string
+ data fantasy.ProviderOptionsData
+ }{
+ {"OpenAI Responses Reasoning Metadata", openai.Name, &openai.ResponsesReasoningMetadata{}},
+ {"Anthropic Reasoning Metadata", anthropic.Name, &anthropic.ReasoningOptionMetadata{}},
+ {"Google Reasoning Metadata", google.Name, &google.ReasoningMetadata{}},
+ {"OpenRouter Metadata", openrouter.Name, &openrouter.ProviderMetadata{}},
+ }
+
+ for _, tc := range metadataTests {
+ t.Run(tc.name, func(t *testing.T) {
+ // Create a response with provider metadata
+ resp := fantasy.Response{
+ Content: []fantasy.Content{
+ fantasy.TextContent{
+ Text: "test",
+ ProviderMetadata: fantasy.ProviderMetadata{
+ tc.providerName: tc.data,
+ },
+ },
+ },
+ }
+
+ // Marshal and unmarshal
+ data, err := json.Marshal(resp)
+ require.NoError(t, err)
+
+ var decoded fantasy.Response
+ err = json.Unmarshal(data, &decoded)
+ require.NoError(t, err)
+
+ // Verify the provider metadata exists
+ textContent, ok := decoded.Content[0].(fantasy.TextContent)
+ require.True(t, ok)
+ _, ok = textContent.ProviderMetadata[tc.providerName]
+ require.True(t, ok, "Provider metadata should be present after round-trip")
+ })
+ }
+}
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/multi_tool.yaml
new file mode 100644
index 000000000..d940adab2
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 815
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Add and multiply the number 2 and 3","type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers"},{"input_schema":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.10.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"msg_012C9wnj2t5QUQ9h5kZsQYbY","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[{"type":"text","text":"I''ll add and multiply the numbers 2 and 3 for you."},{"type":"tool_use","id":"toolu_01RZ48N8E3iuoHP5TqX57bHP","name":"add","input":{"a":2,"b":3}},{"type":"tool_use","id":"toolu_01FLTgP8FxddWfSCSNsD3cpM","name":"multiply","input":{"a":2,"b":3}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":507,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":137,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.215481584s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1361
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Add and multiply the number 2 and 3","type":"text"}],"role":"user"},{"content":[{"text":"I''ll add and multiply the numbers 2 and 3 for you.","type":"text"},{"id":"toolu_01RZ48N8E3iuoHP5TqX57bHP","input":{"a":2,"b":3},"name":"add","type":"tool_use"},{"id":"toolu_01FLTgP8FxddWfSCSNsD3cpM","input":{"a":2,"b":3},"name":"multiply","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_01RZ48N8E3iuoHP5TqX57bHP","content":[{"text":"5","type":"text"}],"type":"tool_result"},{"tool_use_id":"toolu_01FLTgP8FxddWfSCSNsD3cpM","content":[{"text":"6","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers"},{"input_schema":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.10.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"msg_01GXK2MWdJ8vNAhV63dyxdSV","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[{"type":"text","text":"The results are:\n- 2 + 3 = 5\n- 2 Ć 3 = 6"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":705,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":31,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.172643959s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/multi_tool_streaming.yaml
new file mode 100644
index 000000000..20dd84433
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/multi_tool_streaming.yaml
@@ -0,0 +1,151 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 812
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Add and multiply the number 2 and 3","type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant. Always use both add and multiply at the same time.","type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers"},{"input_schema":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.10.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"id":"msg_01Sp6xSRhhVGg9eCXwHHDK4H","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":502,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":4,"service_tier":"standard"}} }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"I'll add an"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"d multiply the numbers 2 and 3 for"} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" you."} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_01GrN36ErVgy85ECZ6pbzBL4","name":"add","input":{}} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"a\": "} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"2"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":", \"b\": 3}"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":1 }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":2,"content_block":{"type":"tool_use","id":"toolu_0113xQa4VtccyoXcHaukkzom","name":"multiply","input":{}}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":2,"delta":{"type":"input_json_delta","partial_json":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":2,"delta":{"type":"input_json_delta","partial_json":"{\"a\": 2"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":2,"delta":{"type":"input_json_delta","partial_json":", \"b\":"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":2,"delta":{"type":"input_json_delta","partial_json":" 3}"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":2 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"input_tokens":502,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":137} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.85757275s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1358
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Add and multiply the number 2 and 3","type":"text"}],"role":"user"},{"content":[{"text":"I''ll add and multiply the numbers 2 and 3 for you.","type":"text"},{"id":"toolu_01GrN36ErVgy85ECZ6pbzBL4","input":{"a":2,"b":3},"name":"add","type":"tool_use"},{"id":"toolu_0113xQa4VtccyoXcHaukkzom","input":{"a":2,"b":3},"name":"multiply","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_01GrN36ErVgy85ECZ6pbzBL4","content":[{"text":"5","type":"text"}],"type":"tool_result"},{"tool_use_id":"toolu_0113xQa4VtccyoXcHaukkzom","content":[{"text":"6","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant. Always use both add and multiply at the same time.","type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers"},{"input_schema":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.10.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"id":"msg_015VFFpA2pw4T7BRXd2sXMNL","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":700,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard"}} }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"The results"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" are:\n- 2 + 3 = "} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"5\n- 2 Ć 3 = 6"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":700,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":31} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.874751333s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/simple.yaml b/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/simple.yaml
new file mode 100644
index 000000000..8ae67fab7
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 205
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Say hi in Portuguese","type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","type":"text"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.10.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"msg_01P9AGfyVhqwFEY82kTBEeip","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[{"type":"text","text":"OlĆ”! (Oh-LAH)\n\nThis is the most common way to say \"hi\" in Portuguese. You could also use \"Oi!\" (OY) which is a bit more casual and friendly."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":16,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":50,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.286588541s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/simple_streaming.yaml
new file mode 100644
index 000000000..c22a1785d
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/simple_streaming.yaml
@@ -0,0 +1,68 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 219
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Say hi in Portuguese","type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","type":"text"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.10.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"id":"msg_01LA3hHsa4pzM8hT7PTXtJGz","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":16,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":4,"service_tier":"standard"}} }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"OlĆ”!"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"\n\n(This is the most common way to say \"hi"} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"\" in Portuguese. You"}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" could also say \"Oi!\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" for a more casual"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" greeting.)"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":16,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":38} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.544292291s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/tool.yaml b/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/tool.yaml
new file mode 100644
index 000000000..a66e33ee3
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 496
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.10.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"msg_015hRye3hWyU1hyU9Vsbzept","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[{"type":"text","text":"I''ll check the weather in Florence, Italy for you."},{"type":"tool_use","id":"toolu_01Dx5rwFL7pCC3c11qUZiSFH","name":"weather","input":{"location":"Florence, Italy"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":394,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":66,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.2413465s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 859
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"},{"content":[{"text":"I''ll check the weather in Florence, Italy for you.","type":"text"},{"id":"toolu_01Dx5rwFL7pCC3c11qUZiSFH","input":{"location":"Florence, Italy"},"name":"weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_01Dx5rwFL7pCC3c11qUZiSFH","content":[{"text":"40 C","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.10.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"msg_01DvxRTrWQwennnPVCKYDpVg","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[{"type":"text","text":"The current weather in Florence, Italy is 40°C (104°F). That''s quite hot! It''s a very warm day in Florence."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":475,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":34,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.441049125s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/tool_streaming.yaml
new file mode 100644
index 000000000..049cb9c21
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicCommon/claude-sonnet-4/tool_streaming.yaml
@@ -0,0 +1,148 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 510
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.10.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"id":"msg_01YNtSKCnRnNJoaUmmcZVnsF","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":394,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard"}}}
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"I'll check the weather in Florence,"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Italy for you."} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_01TQLWhUiZa4j3esJhrzHpRV","name":"weather","input":{}} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"lo"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"cation\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":": "} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\"Florence"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":",Italy\"}"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":1 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"input_tokens":394,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":66} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.173477625s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 872
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"},{"content":[{"text":"I''ll check the weather in Florence, Italy for you.","type":"text"},{"id":"toolu_01TQLWhUiZa4j3esJhrzHpRV","input":{"location":"Florence,Italy"},"name":"weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_01TQLWhUiZa4j3esJhrzHpRV","content":[{"text":"40 C","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.10.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"id":"msg_01Xib3pEmJjt4hNy7sEx4k5S","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":475,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}} }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"The"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" current weather in Florence, Italy shows a temperature of 40°C (104"} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"°F). That's quite hot! Make sure to stay hydrated and seek"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" shade or air conditioning if you're planning to be out"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"doors."} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":475,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":49} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 2.470388833s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/multi_tool.yaml
new file mode 100644
index 000000000..634b4d57a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 889
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Add and multiply the number 2 and 3","cache_control":{"type":"ephemeral"},"type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","cache_control":{"type":"ephemeral"},"type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers"},{"input_schema":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"model":"claude-sonnet-4-20250514","id":"msg_01SznaDwXbs3XRxBLMr2X7T3","type":"message","role":"assistant","content":[{"type":"text","text":"I''ll add and multiply the numbers 2 and 3 for you."},{"type":"tool_use","id":"toolu_01R4MgGUzmDFt4FVjLhPom7k","name":"add","input":{"a":2,"b":3}},{"type":"tool_use","id":"toolu_011jyywbY4Fv6JjWSS6cpVYp","name":"multiply","input":{"a":2,"b":3}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":507,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":137,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.974480333s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1472
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Add and multiply the number 2 and 3","type":"text"}],"role":"user"},{"content":[{"text":"I''ll add and multiply the numbers 2 and 3 for you.","type":"text"},{"id":"toolu_01R4MgGUzmDFt4FVjLhPom7k","input":{"a":2,"b":3},"name":"add","type":"tool_use"},{"id":"toolu_011jyywbY4Fv6JjWSS6cpVYp","input":{"a":2,"b":3},"name":"multiply","cache_control":{"type":"ephemeral"},"type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_01R4MgGUzmDFt4FVjLhPom7k","content":[{"text":"5","type":"text"}],"type":"tool_result"},{"tool_use_id":"toolu_011jyywbY4Fv6JjWSS6cpVYp","cache_control":{"type":"ephemeral"},"content":[{"text":"6","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","cache_control":{"type":"ephemeral"},"type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers"},{"input_schema":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"model":"claude-sonnet-4-20250514","id":"msg_01CNT45ENKCAtApVdKnkwkNc","type":"message","role":"assistant","content":[{"type":"text","text":"The results are:\n- 2 + 3 = 5\n- 2 Ć 3 = 6"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":705,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":31,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.377406042s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/multi_tool_streaming.yaml
new file mode 100644
index 000000000..ff85d8953
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/multi_tool_streaming.yaml
@@ -0,0 +1,163 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 886
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Add and multiply the number 2 and 3","cache_control":{"type":"ephemeral"},"type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant. Always use both add and multiply at the same time.","cache_control":{"type":"ephemeral"},"type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers"},{"input_schema":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_01Ps4SquTmAkLoZixSEW4SrN","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":502,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":4,"service_tier":"standard"}} }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"I'll add an"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"d multiply the numbers 2 and 3 for"} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" you."} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0}
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_014EzUJ1TCJvs3dR7mZZgoyd","name":"add","input":{}} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"a\":"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" 2"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":", "} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\"b\": 3}"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":1 }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":2,"content_block":{"type":"tool_use","id":"toolu_01GYivdvVTotPKuatZiCkQvv","name":"multiply","input":{}} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":2,"delta":{"type":"input_json_delta","partial_json":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":2,"delta":{"type":"input_json_delta","partial_json":"{\"a\": "} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":2,"delta":{"type":"input_json_delta","partial_json":"2"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":2,"delta":{"type":"input_json_delta","partial_json":", \"b\": "} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":2,"delta":{"type":"input_json_delta","partial_json":"3}"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":2 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"input_tokens":502,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":137} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.806945584s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1469
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Add and multiply the number 2 and 3","type":"text"}],"role":"user"},{"content":[{"text":"I''ll add and multiply the numbers 2 and 3 for you.","type":"text"},{"id":"toolu_014EzUJ1TCJvs3dR7mZZgoyd","input":{"a":2,"b":3},"name":"add","type":"tool_use"},{"id":"toolu_01GYivdvVTotPKuatZiCkQvv","input":{"a":2,"b":3},"name":"multiply","cache_control":{"type":"ephemeral"},"type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_014EzUJ1TCJvs3dR7mZZgoyd","content":[{"text":"5","type":"text"}],"type":"tool_result"},{"tool_use_id":"toolu_01GYivdvVTotPKuatZiCkQvv","cache_control":{"type":"ephemeral"},"content":[{"text":"6","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant. Always use both add and multiply at the same time.","cache_control":{"type":"ephemeral"},"type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers"},{"input_schema":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_016tKmgfhWH1tfpDjeFE5JXn","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":700,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}} }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"The"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" results are:\n- Adding"} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" 2 + 3 = 5\n-"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Multiplying 2 Ć "} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"3 = 6"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":700,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":35} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.850997125s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/simple.yaml b/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/simple.yaml
new file mode 100644
index 000000000..c858e2671
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 279
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Say hi in Portuguese","cache_control":{"type":"ephemeral"},"type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","cache_control":{"type":"ephemeral"},"type":"text"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"model":"claude-sonnet-4-20250514","id":"msg_01SM76nbs7k7qZjGy2hihYc6","type":"message","role":"assistant","content":[{"type":"text","text":"OlĆ”! (Oh-LAH)\n\nThis is the most common way to say \"hi\" in Portuguese. You could also say \"Oi!\" (OH-ee) which is more casual and friendly."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":16,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":49,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.99537125s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/simple_streaming.yaml
new file mode 100644
index 000000000..607acf6bc
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/simple_streaming.yaml
@@ -0,0 +1,77 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 293
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Say hi in Portuguese","cache_control":{"type":"ephemeral"},"type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","cache_control":{"type":"ephemeral"},"type":"text"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_01QBAGSzfj2ZoqStejnhgqXh","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":16,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":4,"service_tier":"standard"}} }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"OlĆ”!"}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"\n\n("} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"That's \"hello"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"\" in Portuguese."} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Other common"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" greetings include \""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Oi!\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" for a more casual \""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"hi!\")"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":16,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":35} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 2.247809834s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/tool.yaml b/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/tool.yaml
new file mode 100644
index 000000000..8cc555e9f
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 570
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","cache_control":{"type":"ephemeral"},"type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","cache_control":{"type":"ephemeral"},"type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"model":"claude-sonnet-4-20250514","id":"msg_01Royrn78rAtSCcgQCG9QqoG","type":"message","role":"assistant","content":[{"type":"text","text":"I''ll get the weather information for Florence, Italy for you."},{"type":"tool_use","id":"toolu_01TdBhfkiVbuyrCtsoQ2P4v8","name":"weather","input":{"location":"Florence, Italy"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":394,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":67,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.230270958s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 981
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"},{"content":[{"text":"I''ll get the weather information for Florence, Italy for you.","type":"text"},{"id":"toolu_01TdBhfkiVbuyrCtsoQ2P4v8","input":{"location":"Florence, Italy"},"name":"weather","cache_control":{"type":"ephemeral"},"type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_01TdBhfkiVbuyrCtsoQ2P4v8","cache_control":{"type":"ephemeral"},"content":[{"text":"40 C","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","cache_control":{"type":"ephemeral"},"type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"model":"claude-sonnet-4-20250514","id":"msg_01EiThKJDKp98nTMtjAWoXG6","type":"message","role":"assistant","content":[{"type":"text","text":"The current temperature in Florence, Italy is 40°C (104°F). That''s quite hot! Make sure to stay hydrated and seek shade or air conditioning if you''re planning to be outdoors."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":476,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":46,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.465001083s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/tool_streaming.yaml
new file mode 100644
index 000000000..ce3ebef5e
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicCommonWithCacheControl/claude-sonnet-4/tool_streaming.yaml
@@ -0,0 +1,151 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 584
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","cache_control":{"type":"ephemeral"},"type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","cache_control":{"type":"ephemeral"},"type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_01HzMwmi82NUByB1sP1H4Rtw","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":394,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard"}} }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"I'll check the weather in Florence,"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Italy for you."} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_01TTGTdVydBd7icXtF1o89n7","name":"weather","input":{}} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"locati"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"on"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\": \"Floren"}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"ce, "} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"Italy\"}"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":1 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"input_tokens":394,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":66} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.726456542s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 984
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"},{"content":[{"text":"I''ll check the weather in Florence, Italy for you.","type":"text"},{"id":"toolu_01TTGTdVydBd7icXtF1o89n7","input":{"location":"Florence, Italy"},"name":"weather","cache_control":{"type":"ephemeral"},"type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_01TTGTdVydBd7icXtF1o89n7","cache_control":{"type":"ephemeral"},"content":[{"text":"40 C","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","cache_control":{"type":"ephemeral"},"type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_01UX1WnAwYyv4VsX8Cpuzxcv","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":475,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard"}} }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"The current"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" weather in Florence, Italy is 40"} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"°C (104°F)."} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" That's quite hot! It's a very"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" warm day in Florence"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"."} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":475,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":34} }
+
+ event: message_stop
+ data: {"type":"message_stop"}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 2.045913625s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicObjectGeneration/claude-sonnet-4/complex_object.yaml b/internal/fantasy/providertests/testdata/TestAnthropicObjectGeneration/claude-sonnet-4/complex_object.yaml
new file mode 100644
index 000000000..129f02b51
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicObjectGeneration/claude-sonnet-4/complex_object.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 973
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","tool_choice":{"name":"Book","disable_parallel_tool_use":false,"type":"tool"},"tools":[{"input_schema":{"properties":{"author":{"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"name":"Book","description":"A book with title, author, genres, and publication year"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"model":"claude-sonnet-4-20250514","id":"msg_01UkSBWK7ReA1Jc9w3ZSKrNb","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01C9Z3xQvtkmqxD7fyJ4BHN5","name":"Book","input":{"title":"The Lord of the Rings","author":{"name":"J.R.R. Tolkien","nationality":"British"},"genres":["Fantasy","Adventure","Epic Fantasy","High Fantasy"],"published_year":1954}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":549,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":124,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.668454583s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicObjectGeneration/claude-sonnet-4/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestAnthropicObjectGeneration/claude-sonnet-4/complex_object_streaming.yaml
new file mode 100644
index 000000000..5e9a654ac
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicObjectGeneration/claude-sonnet-4/complex_object_streaming.yaml
@@ -0,0 +1,152 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 987
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","tool_choice":{"name":"Book","disable_parallel_tool_use":false,"type":"tool"},"tools":[{"input_schema":{"properties":{"author":{"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"name":"Book","description":"A book with title, author, genres, and publication year"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_01USjYftFnxQLCtwU6p9mdju","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":549,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":16,"service_tier":"standard"}} }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"tool_use","id":"toolu_01GSfr2xJn2q4zqG46GXNdxt","name":"Book","input":{}} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":""} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"{\"ti"} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"tle\": \"T"} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"he Lord"} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":" of t"} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"he Ring"} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"s\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":", \"author\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":": {\"nam"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"e\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":":\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"J.R.R. To"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"lkien\",\"na"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"tionality\":\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"Bri"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"tish\"}"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":", \"g"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"enre"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"s\": [\"Fanta"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"sy\",\"Adventu"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"re\",\"Epic Fa"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"nta"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"sy\",\"High "} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"Fantasy\"]"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":", \"pub"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"lished_"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"yea"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"r\":"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":" 1954}"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0}
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"input_tokens":549,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":124} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.980122625s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicObjectGeneration/claude-sonnet-4/simple_object.yaml b/internal/fantasy/providertests/testdata/TestAnthropicObjectGeneration/claude-sonnet-4/simple_object.yaml
new file mode 100644
index 000000000..cd685ccb6
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicObjectGeneration/claude-sonnet-4/simple_object.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 637
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris.","type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","tool_choice":{"name":"Person","disable_parallel_tool_use":false,"type":"tool"},"tools":[{"input_schema":{"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"},"name":"Person","description":"A person with name, age, and city"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"model":"claude-sonnet-4-20250514","id":"msg_01NeodXcmcw7q1AnbSJ8ShV4","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_019sLuNYTpv7VTTJEuGWXzki","name":"Person","input":{"name":"Alice","age":30,"city":"Paris"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":454,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":67,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.542812416s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicObjectGeneration/claude-sonnet-4/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestAnthropicObjectGeneration/claude-sonnet-4/simple_object_streaming.yaml
new file mode 100644
index 000000000..cc9828a27
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicObjectGeneration/claude-sonnet-4/simple_object_streaming.yaml
@@ -0,0 +1,89 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 651
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris.","type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","tool_choice":{"name":"Person","disable_parallel_tool_use":false,"type":"tool"},"tools":[{"input_schema":{"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"},"name":"Person","description":"A person with name, age, and city"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_01AihXNzoggoeqPeQuWPMYSo","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":454,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":24,"service_tier":"standard"}} }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"tool_use","id":"toolu_01Midg7qjzUz6pdkS8HcgRY7","name":"Person","input":{}} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":""} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"{\"n"} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"ame\":"} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":" \"Alic"} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"e\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":", \"age\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":": 30"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":", \"c"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"ity\": \"Pa"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"ris\"}"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"input_tokens":454,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":67} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 2.144504667s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicThinking/claude-sonnet-4/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestAnthropicThinking/claude-sonnet-4/thinking-streaming.yaml
new file mode 100644
index 000000000..a7831ede7
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicThinking/claude-sonnet-4/thinking-streaming.yaml
@@ -0,0 +1,160 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 562
+ host: ""
+ body: '{"max_tokens":4096,"messages":[{"content":[{"text":"What''s the weather in Florence, Italy?","type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","type":"text"}],"thinking":{"budget_tokens":4000,"type":"enabled"},"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.10.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"id":"msg_01WBeG2NaYQ8w99747S3n8MZ","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":423,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":6,"service_tier":"standard"}} }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"thinking","thinking":"","signature":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":"The user is asking for"}}
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":" weather information for Florence, Italy. I have"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":" access to a weather function that takes a \"location\" parameter. The"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":" user has provided the location as \"Florence,"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":" Italy\" which is clear and specific. I have"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":" all the required parameters to make this function call."} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"signature_delta","signature":"EsQDCkYICBgCKkBr9+FTcKs+la0OlmRVB4HF/bTERKj+hr9pp9uxwdet2/P99iNZh/vwxm7Cd5wrZD0FnPkUz3DEqXv+ZoIL2fAoEgxOEzQepAptMFJiFJcaDM2L2wJzGec9170N1SIwHhl0DW0hXYbwHTRAR6w9biU0HwUh00oLghjeBusiv40ctsJB4tO/WyOR2f0iH7pZKqsC3UTE2b7nqQUmYP8dEDfnfNdbr24zEaWiZ2QMbwv9ZrwtUy0Wo/ot3n9JMpocHUSwtyKzB4GsMsgr/xtGEl9541AMSFhR1G8y3Ffn22e6pXV7dakwU/vxcBTvdwfBplrBxxJ1zT/ieuQUrdemKCRZS4QVmaVijUpYQMaQF7iCJJPKYI+wBhxT0y0yOoVqORKg2AuRmbkTpMfKZJ5xRBLAeydMhloeKfYswDDisWIChmJlclIro0Jr80OhpohTcQGayY4fjn0A/ir+9PYzLzjGitR3a+/lfHvuTmPC9AnWv3Sp87mddUuJ10jqO9QWXNTnAVdehLiN/heJVjOMkXCstWLVUycEgnfwXEqlNMMFuRAfOwTte0Ls9qHkl3Fzo8ompJiqxF879rSwcSEYAQ=="} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_0171KFcBwn1Z64XzvQfz3sZS","name":"weather","input":{}} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"location"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\": \"F"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"lo"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"rence, I"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"taly"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\"}"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":1 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"input_tokens":423,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":119} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.294270083s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1796
+ host: ""
+ body: '{"max_tokens":4096,"messages":[{"content":[{"text":"What''s the weather in Florence, Italy?","type":"text"}],"role":"user"},{"content":[{"signature":"EsQDCkYICBgCKkBr9+FTcKs+la0OlmRVB4HF/bTERKj+hr9pp9uxwdet2/P99iNZh/vwxm7Cd5wrZD0FnPkUz3DEqXv+ZoIL2fAoEgxOEzQepAptMFJiFJcaDM2L2wJzGec9170N1SIwHhl0DW0hXYbwHTRAR6w9biU0HwUh00oLghjeBusiv40ctsJB4tO/WyOR2f0iH7pZKqsC3UTE2b7nqQUmYP8dEDfnfNdbr24zEaWiZ2QMbwv9ZrwtUy0Wo/ot3n9JMpocHUSwtyKzB4GsMsgr/xtGEl9541AMSFhR1G8y3Ffn22e6pXV7dakwU/vxcBTvdwfBplrBxxJ1zT/ieuQUrdemKCRZS4QVmaVijUpYQMaQF7iCJJPKYI+wBhxT0y0yOoVqORKg2AuRmbkTpMfKZJ5xRBLAeydMhloeKfYswDDisWIChmJlclIro0Jr80OhpohTcQGayY4fjn0A/ir+9PYzLzjGitR3a+/lfHvuTmPC9AnWv3Sp87mddUuJ10jqO9QWXNTnAVdehLiN/heJVjOMkXCstWLVUycEgnfwXEqlNMMFuRAfOwTte0Ls9qHkl3Fzo8ompJiqxF879rSwcSEYAQ==","thinking":"The user is asking for weather information for Florence, Italy. I have access to a weather function that takes a \"location\" parameter. The user has provided the location as \"Florence, Italy\" which is clear and specific. I have all the required parameters to make this function call.","type":"thinking"},{"id":"toolu_0171KFcBwn1Z64XzvQfz3sZS","input":{"location":"Florence, Italy"},"name":"weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_0171KFcBwn1Z64XzvQfz3sZS","content":[{"text":"40 C","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","type":"text"}],"thinking":{"budget_tokens":4000,"type":"enabled"},"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.10.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"id":"msg_013robXNGqrQ66iDpnRyejiu","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":557,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard"}} }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"The current"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" weather in Florence, Italy is 40°C (104°F)."}}
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" That's quite hot! It appears"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" to be a very warm day there"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"."} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":557,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":35}}
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.164435458s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicThinking/claude-sonnet-4/thinking.yaml b/internal/fantasy/providertests/testdata/TestAnthropicThinking/claude-sonnet-4/thinking.yaml
new file mode 100644
index 000000000..cac26c4aa
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicThinking/claude-sonnet-4/thinking.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 548
+ host: ""
+ body: '{"max_tokens":4096,"messages":[{"content":[{"text":"What''s the weather in Florence, Italy?","type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","type":"text"}],"thinking":{"budget_tokens":4000,"type":"enabled"},"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.10.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"msg_0161zGUJcy7n6Gtc3W2yEfEi","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[{"type":"thinking","thinking":"The user is asking for weather information for Florence, Italy. I have access to a weather function that takes a location parameter. The user has provided the location as \"Florence, Italy\" which is specific enough for the weather function.\n\nI should call the weather function with the location parameter set to \"Florence, Italy\".","signature":"EvIDCkYICBgCKkB3OXkd+Z/weJsi/KkBdtuRG6KOJp06/IzU7Jk57DreAI4FgyT9Xqef8INOF0ENXD//orE8oncMe+M72OyRG7FQEgxPaEO4DRV1o5sFWXAaDNTMb6U1NI1BcmYAPCIwzkufbx9sEOQQxPyBOcNFCs/SugbLyRr2IlXwdFmYoDeaOm1DkRFknTct6f6A6EzxKtkCVGlLUEl4LBJeAuluxJbq3PlzewMXa7EEvsi+M4T71uUci/d0RIK2Z5NxNpgTbVqM7shsDImrqR/0gJ/6BxwEptGq1G626mA5DgyfjR0QJ0etDk8kT7iJ33H6BRMGA8DnehmhOUYGTiajWdjgD3/H0S8mVT06swDddMKynOg4sRlr8PvQBDcyDlHTVQUo5SmrOPm8JsOtLfN8nDKTdhU0NofnVVNklOKblM83YuT97HhM269IQEf6rbqKknBZSvKVJOoHkOwTCn60uQj7b1wpVTjI4KRCVnlhRBpVrVyTmveM5kZXNdL/6sHUHboPCUYPbU24aYf/BTPswY2NsbdtpIRS3uHnSyIZ0gOMZA/5pWQbNJYjL5iksP8waiwCgOPkadqo02yQvqDY6XCfVd9LkRdaUQIZOt9IaSDE+9mvGnH025qCd4/sGBy+QRd9T/uNAFmkjeG9wL4oGAE="},{"type":"tool_use","id":"toolu_018GcaTNHipGG9yeZ3srYF9d","name":"weather","input":{"location":"Florence, Italy"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":423,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":126,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.787719958s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1891
+ host: ""
+ body: '{"max_tokens":4096,"messages":[{"content":[{"text":"What''s the weather in Florence, Italy?","type":"text"}],"role":"user"},{"content":[{"signature":"EvIDCkYICBgCKkB3OXkd+Z/weJsi/KkBdtuRG6KOJp06/IzU7Jk57DreAI4FgyT9Xqef8INOF0ENXD//orE8oncMe+M72OyRG7FQEgxPaEO4DRV1o5sFWXAaDNTMb6U1NI1BcmYAPCIwzkufbx9sEOQQxPyBOcNFCs/SugbLyRr2IlXwdFmYoDeaOm1DkRFknTct6f6A6EzxKtkCVGlLUEl4LBJeAuluxJbq3PlzewMXa7EEvsi+M4T71uUci/d0RIK2Z5NxNpgTbVqM7shsDImrqR/0gJ/6BxwEptGq1G626mA5DgyfjR0QJ0etDk8kT7iJ33H6BRMGA8DnehmhOUYGTiajWdjgD3/H0S8mVT06swDddMKynOg4sRlr8PvQBDcyDlHTVQUo5SmrOPm8JsOtLfN8nDKTdhU0NofnVVNklOKblM83YuT97HhM269IQEf6rbqKknBZSvKVJOoHkOwTCn60uQj7b1wpVTjI4KRCVnlhRBpVrVyTmveM5kZXNdL/6sHUHboPCUYPbU24aYf/BTPswY2NsbdtpIRS3uHnSyIZ0gOMZA/5pWQbNJYjL5iksP8waiwCgOPkadqo02yQvqDY6XCfVd9LkRdaUQIZOt9IaSDE+9mvGnH025qCd4/sGBy+QRd9T/uNAFmkjeG9wL4oGAE=","thinking":"The user is asking for weather information for Florence, Italy. I have access to a weather function that takes a location parameter. The user has provided the location as \"Florence, Italy\" which is specific enough for the weather function.\n\nI should call the weather function with the location parameter set to \"Florence, Italy\".","type":"thinking"},{"id":"toolu_018GcaTNHipGG9yeZ3srYF9d","input":{"location":"Florence, Italy"},"name":"weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_018GcaTNHipGG9yeZ3srYF9d","content":[{"text":"40 C","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","type":"text"}],"thinking":{"budget_tokens":4000,"type":"enabled"},"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.10.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"msg_01EpG6sx9WamuPv9k6S2aHDB","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[{"type":"text","text":"The current weather in Florence, Italy is 40°C (104°F). That''s quite hot! Make sure to stay hydrated and seek shade if you''re planning to be outdoors."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":564,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":43,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.560516875s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicThinkingWithCacheControl/claude-sonnet-4/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestAnthropicThinkingWithCacheControl/claude-sonnet-4/thinking-streaming.yaml
new file mode 100644
index 000000000..260e816c7
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicThinkingWithCacheControl/claude-sonnet-4/thinking-streaming.yaml
@@ -0,0 +1,166 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 636
+ host: ""
+ body: '{"max_tokens":4096,"messages":[{"content":[{"text":"What''s the weather in Florence, Italy?","cache_control":{"type":"ephemeral"},"type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","cache_control":{"type":"ephemeral"},"type":"text"}],"thinking":{"budget_tokens":4000,"type":"enabled"},"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_018QLVWxHwCDcmbxmut1XibB","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":423,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":6,"service_tier":"standard"}} }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"thinking","thinking":"","signature":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":"The user is asking for"} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":" weather information for Florence, Italy. I have"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":" access to a weather"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":" function that requires"}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":" a location parameter. The"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":" user has provided the location as \"Florence,"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":" Italy\". I have"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":" all the required parameters to make this function call"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":"."} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"signature_delta","signature":"EqkDCkYICBgCKkDMkVtuKFhL43wYuAZr0LxTAfH7CxEgsPiJdcz/3isjhK8aSzupMCdAAzBvP0wbo0CoAK+d6U8my50fwC6qbKjQEgzeVwbRwVSpMC7a7eIaDDGi/DIlGKGpdo1yXSIwn6eQw8pvNZH3N0x+TKc6d8UWJ85+y+le/fWhIIv/Q/2FnNSZDEbSvLQI6thi94QwKpACRTY5D6hm8bVJ5BIHMyYBLEaxYPjsNyQ9Idf+pkFHY2TKEEvFoqo9liA9RGrb4KOaaJ3n0D6Bqclr69UzTmGs1vvrrKApGO7SleM3V13PG78eKt3QbFu7VjndhYALY2Cf4jDoW6yEHZ8fVvp61kGhyiuxQH8pPqCR8GdkSLOI8O76NHWRt4Zj1MO7LCTaqJNKJdvOc7xKSnQGNjB1Jz3OS+cclNqAhJgJn278Vc0HzIkcX6NdxSM3XjEXMRo7l1oBV04UCtWZD+REpPAt3G1Wz8MJ7mco3F+0tpGnv5nlN5J0+boOZ2o16NASQ7MBPa3a1+F4zgqiVO2TnyxLhy38zn4dfAzoJ1GKedr3UDXBMeMYAQ=="} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0}
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_012Y7zdiwQJuNXf7QjpkJtC6","name":"weather","input":{}} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"location"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\": "} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\"Florence,"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" Italy\"}"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":1 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"input_tokens":423,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":111} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.784653959s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1842
+ host: ""
+ body: '{"max_tokens":4096,"messages":[{"content":[{"text":"What''s the weather in Florence, Italy?","type":"text"}],"role":"user"},{"content":[{"signature":"EqkDCkYICBgCKkDMkVtuKFhL43wYuAZr0LxTAfH7CxEgsPiJdcz/3isjhK8aSzupMCdAAzBvP0wbo0CoAK+d6U8my50fwC6qbKjQEgzeVwbRwVSpMC7a7eIaDDGi/DIlGKGpdo1yXSIwn6eQw8pvNZH3N0x+TKc6d8UWJ85+y+le/fWhIIv/Q/2FnNSZDEbSvLQI6thi94QwKpACRTY5D6hm8bVJ5BIHMyYBLEaxYPjsNyQ9Idf+pkFHY2TKEEvFoqo9liA9RGrb4KOaaJ3n0D6Bqclr69UzTmGs1vvrrKApGO7SleM3V13PG78eKt3QbFu7VjndhYALY2Cf4jDoW6yEHZ8fVvp61kGhyiuxQH8pPqCR8GdkSLOI8O76NHWRt4Zj1MO7LCTaqJNKJdvOc7xKSnQGNjB1Jz3OS+cclNqAhJgJn278Vc0HzIkcX6NdxSM3XjEXMRo7l1oBV04UCtWZD+REpPAt3G1Wz8MJ7mco3F+0tpGnv5nlN5J0+boOZ2o16NASQ7MBPa3a1+F4zgqiVO2TnyxLhy38zn4dfAzoJ1GKedr3UDXBMeMYAQ==","thinking":"The user is asking for weather information for Florence, Italy. I have access to a weather function that requires a location parameter. The user has provided the location as \"Florence, Italy\". I have all the required parameters to make this function call.","type":"thinking"},{"id":"toolu_012Y7zdiwQJuNXf7QjpkJtC6","input":{"location":"Florence, Italy"},"name":"weather","cache_control":{"type":"ephemeral"},"type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_012Y7zdiwQJuNXf7QjpkJtC6","cache_control":{"type":"ephemeral"},"content":[{"text":"40 C","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","cache_control":{"type":"ephemeral"},"type":"text"}],"thinking":{"budget_tokens":4000,"type":"enabled"},"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_01RtDAbGZhKwuFUM9xy3bE72","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":549,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}} }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"The"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" current weather in Florence, Italy is "} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"40°C (104°F)."} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" That's quite hot! It"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"'s a very warm day in"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Florence."} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0}
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":549,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":34} }
+
+ event: message_stop
+ data: {"type":"message_stop"}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 2.0182445s
diff --git a/internal/fantasy/providertests/testdata/TestAnthropicThinkingWithCacheControl/claude-sonnet-4/thinking.yaml b/internal/fantasy/providertests/testdata/TestAnthropicThinkingWithCacheControl/claude-sonnet-4/thinking.yaml
new file mode 100644
index 000000000..bce266d25
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAnthropicThinkingWithCacheControl/claude-sonnet-4/thinking.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 622
+ host: ""
+ body: '{"max_tokens":4096,"messages":[{"content":[{"text":"What''s the weather in Florence, Italy?","cache_control":{"type":"ephemeral"},"type":"text"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","cache_control":{"type":"ephemeral"},"type":"text"}],"thinking":{"budget_tokens":4000,"type":"enabled"},"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"model":"claude-sonnet-4-20250514","id":"msg_019nCdrqNy56N4FPDPkMaz7B","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"The user is asking for weather information for Florence, Italy. I have a weather function available that takes a location parameter. The user has provided \"Florence, Italy\" as the location. I have all the required parameters to make the function call.","signature":"EqQDCkYICBgCKkD+6F3ZCJ3CoiNs91jnjkz/6xYefJjve+nbgY/runWHxGeBEg21iA6vjJVq7OceBDUlc+TFtcdi0WkUTiiBe0S5EgxwzS43u6Xgdl6soBAaDKzHQ0Z1Vrcz7LHSUCIwU6Qn02eS0AhhP5SpNdLRzSPWLN3oHDC3vhxs4wiNY4TkWpXa9nyIRhwUKNd5ud+uKosCJgjHGR/uLuODWUEGlJbrxAhr3xrQbciN/sDfV4tqfPOj+t5tm96khBOGNXXIO/SE3If0wlexbIGis17tQxnH6z0MRB7SiRzS6CjWzMK361uwv2pgUgy9lHKsbARcjtFCaCCrFpFLPO0lySJK0D60RmPO6DmFfkamYAcCT1870iZrI+RB0Hu7xbWnoZ3VURmxBv+VxX7cRll6zfcgOhTVVtVFdgghuuHujtyPMMau3HiZUJVv4juzrSNCIS15LP2RfCFGJ6Xes6hoWXeGcVQOeJmbJ1s3E2prELzM31wkeEE26ftwfF7VF4yCt62ocEuc07zsycVKRRZEDBe9CEb9Ny+HW4dbrEX/DMvPGAE="},{"type":"tool_use","id":"toolu_014gjpHAaavY4696WA2WGDLS","name":"weather","input":{"location":"Florence, Italy"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":423,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":111,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.529551375s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1816
+ host: ""
+ body: '{"max_tokens":4096,"messages":[{"content":[{"text":"What''s the weather in Florence, Italy?","type":"text"}],"role":"user"},{"content":[{"signature":"EqQDCkYICBgCKkD+6F3ZCJ3CoiNs91jnjkz/6xYefJjve+nbgY/runWHxGeBEg21iA6vjJVq7OceBDUlc+TFtcdi0WkUTiiBe0S5EgxwzS43u6Xgdl6soBAaDKzHQ0Z1Vrcz7LHSUCIwU6Qn02eS0AhhP5SpNdLRzSPWLN3oHDC3vhxs4wiNY4TkWpXa9nyIRhwUKNd5ud+uKosCJgjHGR/uLuODWUEGlJbrxAhr3xrQbciN/sDfV4tqfPOj+t5tm96khBOGNXXIO/SE3If0wlexbIGis17tQxnH6z0MRB7SiRzS6CjWzMK361uwv2pgUgy9lHKsbARcjtFCaCCrFpFLPO0lySJK0D60RmPO6DmFfkamYAcCT1870iZrI+RB0Hu7xbWnoZ3VURmxBv+VxX7cRll6zfcgOhTVVtVFdgghuuHujtyPMMau3HiZUJVv4juzrSNCIS15LP2RfCFGJ6Xes6hoWXeGcVQOeJmbJ1s3E2prELzM31wkeEE26ftwfF7VF4yCt62ocEuc07zsycVKRRZEDBe9CEb9Ny+HW4dbrEX/DMvPGAE=","thinking":"The user is asking for weather information for Florence, Italy. I have a weather function available that takes a location parameter. The user has provided \"Florence, Italy\" as the location. I have all the required parameters to make the function call.","type":"thinking"},{"id":"toolu_014gjpHAaavY4696WA2WGDLS","input":{"location":"Florence, Italy"},"name":"weather","cache_control":{"type":"ephemeral"},"type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_014gjpHAaavY4696WA2WGDLS","cache_control":{"type":"ephemeral"},"content":[{"text":"40 C","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","cache_control":{"type":"ephemeral"},"type":"text"}],"thinking":{"budget_tokens":4000,"type":"enabled"},"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"model":"claude-sonnet-4-20250514","id":"msg_011vbhawoMAwZzuGJEzTmfaK","type":"message","role":"assistant","content":[{"type":"text","text":"The current weather in Florence, Italy is 40°C (104°F). That''s quite hot! It''s a very warm day in Florence."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":549,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":34,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.484467584s
diff --git a/internal/fantasy/providertests/testdata/TestAzureCommon/azure-gpt-5-mini/simple.yaml b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-gpt-5-mini/simple.yaml
new file mode 100644
index 000000000..5da1db780
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-gpt-5-mini/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 171
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"gpt-5-mini","max_completion_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 1205
+ body: |
+ {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"protected_material_code":{"filtered":false,"detected":false},"protected_material_text":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"finish_reason":"stop","index":0,"logprobs":null,"message":{"annotations":[],"content":"OlĆ”!","refusal":null,"role":"assistant"}}],"created":1761842954,"id":"chatcmpl-CWQ7mNYuvWWQimXnUMuiLAxVCoNRW","model":"gpt-5-mini-2025-08-07","object":"chat.completion","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"system_fingerprint":null,"usage":{"completion_tokens":76,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":64,"rejected_prediction_tokens":0},"prompt_tokens":19,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":95}}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.767307375s
diff --git a/internal/fantasy/providertests/testdata/TestAzureCommon/azure-gpt-5-mini/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-gpt-5-mini/simple_streaming.yaml
new file mode 100644
index 000000000..657125901
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-gpt-5-mini/simple_streaming.yaml
@@ -0,0 +1,62 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 225
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"gpt-5-mini","max_completion_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}]}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"content":"","refusal":null,"role":"assistant"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842957,"id":"chatcmpl-CWQ7puA20Xq1q7lREx3It7GAIshNJ","model":"gpt-5-mini-2025-08-07","obfuscation":"zV0z0Nhm4vBJPe","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"OlĆ”"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842957,"id":"chatcmpl-CWQ7puA20Xq1q7lREx3It7GAIshNJ","model":"gpt-5-mini-2025-08-07","obfuscation":"bAjQTaqR0x0H0","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"!"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842957,"id":"chatcmpl-CWQ7puA20Xq1q7lREx3It7GAIshNJ","model":"gpt-5-mini-2025-08-07","obfuscation":"5SfhBKVU1ZExC0w","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" ("},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842957,"id":"chatcmpl-CWQ7puA20Xq1q7lREx3It7GAIshNJ","model":"gpt-5-mini-2025-08-07","obfuscation":"WkSeDVRMxOyjtP","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"tamb"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842957,"id":"chatcmpl-CWQ7puA20Xq1q7lREx3It7GAIshNJ","model":"gpt-5-mini-2025-08-07","obfuscation":"pNiSihK5iZcs","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"Ʃm"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842957,"id":"chatcmpl-CWQ7puA20Xq1q7lREx3It7GAIshNJ","model":"gpt-5-mini-2025-08-07","obfuscation":"xECBxJwCJ42Ktg","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" pode"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842957,"id":"chatcmpl-CWQ7puA20Xq1q7lREx3It7GAIshNJ","model":"gpt-5-mini-2025-08-07","obfuscation":"j5vLZXmCrsl","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" dizer"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842957,"id":"chatcmpl-CWQ7puA20Xq1q7lREx3It7GAIshNJ","model":"gpt-5-mini-2025-08-07","obfuscation":"f6uQzkBbn5","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" \""},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842957,"id":"chatcmpl-CWQ7puA20Xq1q7lREx3It7GAIshNJ","model":"gpt-5-mini-2025-08-07","obfuscation":"4OGZk82dzZvaF","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"Oi"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842957,"id":"chatcmpl-CWQ7puA20Xq1q7lREx3It7GAIshNJ","model":"gpt-5-mini-2025-08-07","obfuscation":"aY4hMT7w5iE0gy","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"!\")"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842957,"id":"chatcmpl-CWQ7puA20Xq1q7lREx3It7GAIshNJ","model":"gpt-5-mini-2025-08-07","obfuscation":"bX0oyMMZTDqs","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{},"finish_reason":"stop","index":0,"logprobs":null}],"created":1761842957,"id":"chatcmpl-CWQ7puA20Xq1q7lREx3It7GAIshNJ","model":"gpt-5-mini-2025-08-07","obfuscation":"IkpictBD1v","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[],"created":1761842957,"id":"chatcmpl-CWQ7puA20Xq1q7lREx3It7GAIshNJ","model":"gpt-5-mini-2025-08-07","obfuscation":"MQpC96hAsnU","object":"chat.completion.chunk","system_fingerprint":null,"usage":{"completion_tokens":148,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":128,"rejected_prediction_tokens":0},"prompt_tokens":19,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":167}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 2.602852625s
diff --git a/internal/fantasy/providertests/testdata/TestAzureCommon/azure-gpt-5-mini/tool.yaml b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-gpt-5-mini/tool.yaml
new file mode 100644
index 000000000..f525af548
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-gpt-5-mini/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 463
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"gpt-5-mini","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 1050
+ body: |
+ {"choices":[{"content_filter_results":{},"finish_reason":"tool_calls","index":0,"logprobs":null,"message":{"annotations":[],"content":null,"refusal":null,"role":"assistant","tool_calls":[{"function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"id":"call_Qfrepi6GMFE2a9QE9JiXptZt","type":"function"}]}}],"created":1761842959,"id":"chatcmpl-CWQ7rrdJOXqm8pE5y29e3exiAHJe5","model":"gpt-5-mini-2025-08-07","object":"chat.completion","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"system_fingerprint":null,"usage":{"completion_tokens":26,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens":145,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":171}}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.042717709s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 715
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_Qfrepi6GMFE2a9QE9JiXptZt","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_Qfrepi6GMFE2a9QE9JiXptZt","role":"tool"}],"model":"gpt-5-mini","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 1434
+ body: |
+ {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"protected_material_text":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"finish_reason":"stop","index":0,"logprobs":null,"message":{"annotations":[],"content":"Current temperature in Florence, Italy: 40 °C (104 °F).\n\nThat's very hot ā consider staying hydrated, avoiding prolonged sun exposure or strenuous outdoor activity during midday, and checking local heat warnings. Would you like an hourly forecast, a 7-day outlook, or any other details?","refusal":null,"role":"assistant"}}],"created":1761842961,"id":"chatcmpl-CWQ7t0TV6CZZN7q9HDxlkG8FMHbTN","model":"gpt-5-mini-2025-08-07","object":"chat.completion","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"system_fingerprint":null,"usage":{"completion_tokens":261,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":192,"rejected_prediction_tokens":0},"prompt_tokens":176,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":437}}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 6.188168959s
diff --git a/internal/fantasy/providertests/testdata/TestAzureCommon/azure-gpt-5-mini/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-gpt-5-mini/tool_streaming.yaml
new file mode 100644
index 000000000..f40d45c33
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-gpt-5-mini/tool_streaming.yaml
@@ -0,0 +1,241 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 517
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"gpt-5-mini","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}]}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"content":null,"refusal":null,"role":"assistant","tool_calls":[{"function":{"arguments":"","name":"weather"},"id":"call_WFbjblhLkFWD9MLJyBZIYfa8","index":0,"type":"function"}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842968,"id":"chatcmpl-CWQ80r4XwxEJf2WSuHTmxcFkBoDjz","model":"gpt-5-mini-2025-08-07","obfuscation":"vJXSYcBaeCSjS","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"{\""},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842968,"id":"chatcmpl-CWQ80r4XwxEJf2WSuHTmxcFkBoDjz","model":"gpt-5-mini-2025-08-07","obfuscation":"b9Y","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"location"},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842968,"id":"chatcmpl-CWQ80r4XwxEJf2WSuHTmxcFkBoDjz","model":"gpt-5-mini-2025-08-07","obfuscation":"a8RF0QYq8yeFA2","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"\":\""},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842968,"id":"chatcmpl-CWQ80r4XwxEJf2WSuHTmxcFkBoDjz","model":"gpt-5-mini-2025-08-07","obfuscation":"m","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"Flor"},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842968,"id":"chatcmpl-CWQ80r4XwxEJf2WSuHTmxcFkBoDjz","model":"gpt-5-mini-2025-08-07","obfuscation":"Ym","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"ence"},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842968,"id":"chatcmpl-CWQ80r4XwxEJf2WSuHTmxcFkBoDjz","model":"gpt-5-mini-2025-08-07","obfuscation":"et","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":","},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842968,"id":"chatcmpl-CWQ80r4XwxEJf2WSuHTmxcFkBoDjz","model":"gpt-5-mini-2025-08-07","obfuscation":"8zW5E","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":" Italy"},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842968,"id":"chatcmpl-CWQ80r4XwxEJf2WSuHTmxcFkBoDjz","model":"gpt-5-mini-2025-08-07","obfuscation":"","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"\"}"},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842968,"id":"chatcmpl-CWQ80r4XwxEJf2WSuHTmxcFkBoDjz","model":"gpt-5-mini-2025-08-07","obfuscation":"3Li","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{},"finish_reason":"tool_calls","index":0,"logprobs":null}],"created":1761842968,"id":"chatcmpl-CWQ80r4XwxEJf2WSuHTmxcFkBoDjz","model":"gpt-5-mini-2025-08-07","obfuscation":"OdNH","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[],"created":1761842968,"id":"chatcmpl-CWQ80r4XwxEJf2WSuHTmxcFkBoDjz","model":"gpt-5-mini-2025-08-07","obfuscation":"63Mqj9Hvoz","object":"chat.completion.chunk","system_fingerprint":null,"usage":{"completion_tokens":154,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":128,"rejected_prediction_tokens":0},"prompt_tokens":145,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":299}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 3.996220958s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 769
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_WFbjblhLkFWD9MLJyBZIYfa8","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_WFbjblhLkFWD9MLJyBZIYfa8","role":"tool"}],"model":"gpt-5-mini","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}]}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"content":"","refusal":null,"role":"assistant"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"31ohoZjadUIMY7","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"Current"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"1Fc7UNTIF","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" temperature"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"aCxc","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" in"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"T9GNQ70Z8hNaE","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" Florence"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"opSu26D","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":","},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"TsN8SM5lv7KfDNs","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" Italy"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"tYpH4n7zPk","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":":"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"Yg5iXL3dpwakuRQ","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" "},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"vfqgpOdnPhVUT5B","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"40"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"Gzg6vg5reXdPKK","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" °"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"nCl9nrNZVKHIX6","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"C"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"hFyT92OEAI8u1YX","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" ("},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"gN0BfZuyaFCZ3t","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"about"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"Q4tjkF1rPur","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" "},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"veP3crKB22a9YOr","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"104"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"GRj7GGqlQUcGX","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" °"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"7c0tVnsjlvO7Mu","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"F"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"xVC0jWLFWlwPfNn","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":").\n\n"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"PDYACeJXKz","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"That's"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"ZqijVzfdL3","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" very"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"wNFG8aWqZot","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" hot"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"ZfuqAqqCtaq0","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" ā"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"HHtmcJuOfgVmdK","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" consider"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"yxzr7Ul","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":":\n"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"U0KEaVVODjFGs","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"-"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"5uwIrMW93ii4Hxg","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" Stay"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"1eU1vpVoqd3","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" hydrated"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"kUW29Q2","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" and"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"wF52budGGDiH","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" seek"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"pC1dhq0FofE","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" shade"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"kJvkcB9GTA","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"/"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"ICTddIPYaNCIZOU","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"air"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"CR8UnJZQra82V","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" conditioning"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"Hl8","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"\n"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"21xaXflEGZ4RlT","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"-"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"gDNzFKt7ZJHZt31","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" Limit"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"1LY629BG3r","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" strenuous"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"dtEDq9","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" outdoor"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"AhhmGCNC","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" activity"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"vgsiQ07","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" during"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"qmzgc0rTP","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" midday"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"r3CW8fNP1","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"\n"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"eJguL96SizX37V","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"-"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"yRsKXiEmvIpPNGM","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" Wear"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"6v5D9hep8DT","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" light"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"GjAhTZFdKQ","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" clothing"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"6eI60a6","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":","},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"odmBjOeXSYfqO0E","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" a"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"xZpDTnNUgtqoGt","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" hat"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"nzJhcXAx70KX","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":","},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"26Ef1iOSqin82Oh","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" and"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"tyNnDq1fevj3","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" sunscreen"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"7HNTYO","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"\n\n"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"cfFJRATLVYff","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"Would"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"J41N8hHrGPZ","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" you"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"b8WyGVBkx6tm","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" like"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"7EApxYjDgSu","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" a"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"UZd5rACfceOB6h","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" short"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"j0uor3Cu6D","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"-term"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"a96BZJ6ceRZ","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" forecast"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"QeOqCTz","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":","},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"2z9eXOYEWBR3kUj","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" hourly"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"Cgi24D3mW","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" temps"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"9cT8DF2ga8","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":","},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"WiMLdceuybAlj9c","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" or"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"cnNrlBkMTfxGM","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" advice"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"OH8ufdCMF","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" for"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"XDcxeossOiFm","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" travel"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"t9NoOZkZe","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"/out"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"WIUoUD8qTMwU","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"door"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"4Liibim1NHhm","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" plans"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"eYY3eZAgQf","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"?"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"7AUAgW0JUU6rcyY","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{},"finish_reason":"stop","index":0,"logprobs":null}],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"q9zzoCPBoE","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[],"created":1761842972,"id":"chatcmpl-CWQ84HNPCUXZ59lNv22vwvIUppIBm","model":"gpt-5-mini-2025-08-07","obfuscation":"fzJC7PzN3I","object":"chat.completion.chunk","system_fingerprint":null,"usage":{"completion_tokens":210,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":128,"rejected_prediction_tokens":0},"prompt_tokens":176,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":386}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 4.104046292s
diff --git a/internal/fantasy/providertests/testdata/TestAzureCommon/azure-grok-3-mini/simple.yaml b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-grok-3-mini/simple.yaml
new file mode 100644
index 000000000..d6e7b1804
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-grok-3-mini/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 161
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"grok-3-mini","max_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "{\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"protected_material_code\":{\"filtered\":false,\"detected\":false},\"protected_material_text\":{\"filtered\":false,\"detected\":false},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"finish_reason\":\"stop\",\"index\":0,\"logprobs\":null,\"message\":{\"content\":\"Hi! In Portuguese, \\\"hi\\\" is commonly said as \\\"oi\\\". \U0001F60A\",\"reasoning_content\":\"First, the user asked me to \\\"Say hi in Portuguese.\\\" So, I need to respond in a way that's helpful and directly addresses the request.\\n\\nThe most common way to say \\\"hi\\\" in Portuguese is \\\"oi\\\". That's informal and widely used. There's also \\\"olĆ”\\\" which is more formal, similar to \\\"hello\\\". Since the user said \\\"hi\\\", which is casual, \\\"oi\\\" might be more appropriate. But I should confirm if I need to be more precise.\\n\\nAs a helpful assistant, I could provide a bit more context to make the response educational. For example, I could say, \\\"Hi! In Portuguese, 'hi' is commonly said as 'oi'.\\\" This way, I'm not just giving a one-word answer but engaging more.\\n\\nMy system prompt is: \\\"You are a helpful assistant.\\\" So, I should aim to be friendly, accurate, and engaging.\\n\\nPossible responses:\\n\\n1. Simple: \\\"Oi!\\\" ā This directly says \\\"hi\\\" in Portuguese.\\n\\n2. More informative: \\\"Sure, in Portuguese, 'hi' is 'oi'.\\\"\\n\\n3. Friendly and engaging: \\\"Hello! If you want to say 'hi' in Portuguese, it's 'oi'.\\\"\\n\\nSince the user said \\\"Say hi in Portuguese,\\\" they might expect me to say it, so I could start with \\\"Oi!\\\" and then explain.\\n\\nTo make it conversational, I could say, \\\"Hi there! In Portuguese, that would be 'oi'.\\\"\\n\\nI should ensure the response is in English unless specified, as the user asked in English. So, I'll respond in English but include the Portuguese word.\\n\\nFinally, keep it concise but helpful.\\n\\nCrafted response: \\\"Hi! In Portuguese, 'hi' is commonly said as 'oi'.\\\"\",\"refusal\":null,\"role\":\"assistant\",\"tool_calls\":null},\"stop_reason\":null}],\"created\":1761842977,\"id\":\"4b64bbd0-309b-4f3d-9821-14274e330bb1_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion\",\"prompt_filter_results\":[{\"prompt_index\":0,\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"jailbreak\":{\"filtered\":false,\"detected\":false},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}}}],\"usage\":{\"audio_prompt_tokens\":0,\"completion_tokens\":17,\"completion_tokens_details\":{\"accepted_prediction_tokens\":0,\"audio_tokens\":0,\"reasoning_tokens\":357,\"rejected_prediction_tokens\":0},\"num_sources_used\":0,\"prompt_tokens\":20,\"prompt_tokens_details\":{\"audio_tokens\":0,\"cached_tokens\":0,\"image_tokens\":0,\"text_tokens\":20},\"total_tokens\":394}}\n"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.243653042s
diff --git a/internal/fantasy/providertests/testdata/TestAzureCommon/azure-grok-3-mini/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-grok-3-mini/simple_streaming.yaml
new file mode 100644
index 000000000..9a409a767
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-grok-3-mini/simple_streaming.yaml
@@ -0,0 +1,32 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 215
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"grok-3-mini","max_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"choices\":[],\"created\":0,\"id\":\"\",\"model\":\"\",\"object\":\"\",\"prompt_filter_results\":[{\"prompt_index\":0,\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"jailbreak\":{\"filtered\":false,\"detected\":false},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}}}]}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"First\",\"role\":\"assistant\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" the\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" user\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" asked\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" me\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" to\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Say\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" hi\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" in\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Portuguese\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" So\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" I\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" need\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" to\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" respond\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" by\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" greeting\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" in\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Portuguese\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\n\\n\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"The\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" word\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" for\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"hi\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"\\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" in\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Portuguese\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" is\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"oi\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"\\\".\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" It's\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" a\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" common\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" informal\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" greeting\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" I\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" should\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" confirm\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" if\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" this\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" is\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" correct\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Yes\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"oi\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"\\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" means\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"hi\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"\\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" or\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"hello\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"\\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" in\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Brazilian\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Portuguese\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" which\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" is\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" the\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" most\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" widely\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" spoken\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" variant\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" In\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" European\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Portuguese\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"ol\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Ć”\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"\\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" is\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" also\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" used\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" but\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"oi\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"\\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" is\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" universally\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" understood\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\n\\n\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"To\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" be\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" helpful\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" I\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" should\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" keep\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" it\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" simple\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" and\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" direct\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" since\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" the\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" user\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" just\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" said\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Say\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" hi\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" in\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Portuguese\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\\"\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" I\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" don't\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" want\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" to\"},\"index\":0}],\"created\":1761842981,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" over\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"com\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"plicate\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" it\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\n\\n\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"As\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" an\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" AI\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" I\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" can\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" add\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" a\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" bit\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" of\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" friendliness\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" For\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" example\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" I\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" could\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" say\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Hi\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" in\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Portuguese\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" is\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" '\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"oi\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"'\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"!\\\"\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" or\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" something\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" similar\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" to\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" make\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" it\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" engaging\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\n\\n\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Possible\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" responses\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\":\\n\\n\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"-\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Oi\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"!\\\"\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" (\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"just\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" saying\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" it\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" directly\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\")\\n\\n\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"-\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Hello\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" in\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Portuguese\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" is\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" '\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"oi\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"'\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\\"\\n\\n\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"-\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Sure\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" in\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Portuguese\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" '\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"hi\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"'\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" is\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" '\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"oi\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"'\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\\"\\n\\n\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"I\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" should\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" ensure\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" my\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" response\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" is\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" in\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" English\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" initially\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" to\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" explain\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" then\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" provide\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" the\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Portuguese\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" word\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" as\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" the\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" user\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" asked\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" in\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" English\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\n\\n\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"The\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" user\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" said\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Say\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" hi\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" in\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Portuguese\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\\\"\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" which\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" could\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" mean\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" to\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" utter\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" the\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" greeting\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" in\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Portuguese\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" So\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" perhaps\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" just\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" responding\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" with\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Oi\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"!\\\"\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" would\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" suffice\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" But\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" to\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" be\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" more\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" informative\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" I\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" could\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" say\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Hi\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"!\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" In\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Portuguese\"},\"index\":0}],\"created\":1761842982,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" it's\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" '\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"oi\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"'\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\\"\\n\\n\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Re\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"-reading\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" the\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" user's\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" message\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\":\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Say\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" hi\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" in\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Portuguese\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\\"\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" It's\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" a\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" command\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" so\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" I\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" should\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" directly\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" say\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" the\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" greeting\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\n\\n\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"In\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" the\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" context\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" of\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" being\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" a\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" helpful\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" assistant\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" I\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" can\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" make\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" it\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" conversational\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" For\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" instance\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\":\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Hello\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"!\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" If\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" you\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" want\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" to\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" say\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" '\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"hi\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"'\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" in\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Portuguese\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" it's\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" '\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"oi\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"'\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\\"\\n\\n\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Finally\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" end\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" with\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" the\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" greeting\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" to\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" make\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" it\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" natural\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\n\\n\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Structure\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" my\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" response\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\":\\n\\n\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"1\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" A\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"cknowledge\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" the\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" request\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\n\\n\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"2\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Provide\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" the\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" information\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\n\\n\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"3\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Perhaps\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" add\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" a\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" fun\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" fact\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" or\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" ask\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" if\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" they\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" need\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" more\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" help\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" but\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" keep\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" it\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" concise\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\n\\n\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Response\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" idea\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\":\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Sure\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" '\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"hi\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"'\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" in\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Portuguese\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" is\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" '\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"oi\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"'!\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" Oi\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"!\\\"\\n\\n\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"This\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" way\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" I'm\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" helpful\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" and\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" engaging\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\n\\n\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"Remember\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" my\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" system\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" prompt\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\":\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" \\\"\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\"You\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" are\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" a\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" helpful\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" assistant\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\\\"\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" So\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\",\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" prioritize\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" being\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" helpful\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" and\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\" accurate\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{\"reasoning_content\":\".\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"delta\":{\"content\":\"Sure\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"delta\":{\"content\":\",\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"delta\":{\"content\":\" \\\"\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"delta\":{\"content\":\"hi\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"delta\":{\"content\":\"\\\"\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"delta\":{\"content\":\" in\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"delta\":{\"content\":\" Portuguese\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"delta\":{\"content\":\" is\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"delta\":{\"content\":\" \\\"\"},\"index\":0}],\"created\":1761842983,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"delta\":{\"content\":\"oi\"},\"index\":0}],\"created\":1761842984,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"delta\":{\"content\":\"\\\"!\"},\"index\":0}],\"created\":1761842984,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"delta\":{\"content\":\" \\n\\n\"},\"index\":0}],\"created\":1761842984,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"delta\":{\"content\":\"Oi\"},\"index\":0}],\"created\":1761842984,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"delta\":{\"content\":\"!\"},\"index\":0}],\"created\":1761842984,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"delta\":{\"content\":\" \"},\"index\":0}],\"created\":1761842984,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{\"hate\":{\"filtered\":false,\"severity\":\"safe\"},\"self_harm\":{\"filtered\":false,\"severity\":\"safe\"},\"sexual\":{\"filtered\":false,\"severity\":\"safe\"},\"violence\":{\"filtered\":false,\"severity\":\"safe\"}},\"delta\":{\"content\":\"\U0001F60A\"},\"index\":0}],\"created\":1761842984,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[{\"content_filter_results\":{},\"delta\":{},\"finish_reason\":\"stop\",\"index\":0}],\"created\":1761842984,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\"}\n\ndata: {\"choices\":[],\"created\":1761842984,\"id\":\"c56398c4-725e-4a7d-8227-23af452c6547_sidecar\",\"model\":\"grok-3-mini-high\",\"object\":\"chat.completion.chunk\",\"system_fingerprint\":\"fp_d33f0040b9\",\"usage\":{\"completion_tokens\":16,\"completion_tokens_details\":{\"accepted_prediction_tokens\":0,\"audio_tokens\":0,\"reasoning_tokens\":431,\"rejected_prediction_tokens\":0},\"num_sources_used\":0,\"prompt_tokens\":20,\"prompt_tokens_details\":{\"audio_tokens\":0,\"cached_tokens\":0,\"image_tokens\":0,\"text_tokens\":20},\"total_tokens\":467}}\n\ndata: [DONE]\n\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 408.646834ms
diff --git a/internal/fantasy/providertests/testdata/TestAzureCommon/azure-grok-3-mini/tool.yaml b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-grok-3-mini/tool.yaml
new file mode 100644
index 000000000..801f01c67
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-grok-3-mini/tool.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 453
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"grok-3-mini","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {"choices":[{"content_filter_results":{},"finish_reason":"tool_calls","index":0,"logprobs":null,"message":{"content":"","reasoning_content":"First, the user is asking about the weather in Florence, Italy. I have an available function called \"weather\" that can get weather information for a location.\n\nThe function description is: \"Get weather information for a location\". The parameters require a \"location\" which is a string describing the city.\n\nThe user provided \"Florence, Italy\", which clearly specifies the city and country. This matches the required parameter for the \"weather\" function.\n\nAll required parameters are provided and inferable. The location is \"Florence, Italy\", so I can use that directly.\n\nI should call the function if it can address the query. Here, it directly can, so I need to trigger a function call.\n\nThe function call format is specific: use \u003cfunction_call\u003e tags with JSON inside, like \u003cfunction_call\u003e{\"action\": \"function_name\", \"action_input\": {\"parameter\": \"argument\"}}\u003c/function_call\u003e.\n\nFor this, the action is \"weather\", and the action_input should have \"location\" with the value \"Florence, Italy\".\n\nI don't need to add any extra response text unless necessary. The instructions say to keep responses clear and not verbose, so I should just make the function call if that's the next step.\n\nThis is a single-turn query that can be handled by the function, so I'll call it directly.\n\nFinal decision: Call the \"weather\" function with the location \"Florence, Italy\".","refusal":null,"role":"assistant","tool_calls":[{"function":{"arguments":"{\"location\":\"Florence, Italy\"}","call_id":null,"name":"weather"},"id":"call_03413597","type":"function"}]},"stop_reason":null}],"created":1761842984,"id":"0a9e19c6-4d29-4a05-a60d-2923fdd75f2f_sidecar","model":"grok-3-mini-high","object":"chat.completion","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"usage":{"audio_prompt_tokens":0,"completion_tokens":27,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":281,"rejected_prediction_tokens":0},"num_sources_used":0,"prompt_tokens":288,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0,"image_tokens":0,"text_tokens":288},"total_tokens":596}}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.080312709s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 673
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_03413597","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_03413597","role":"tool"}],"model":"grok-3-mini","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"protected_material_code":{"filtered":false,"detected":false},"protected_material_text":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"finish_reason":"stop","index":0,"logprobs":null,"message":{"content":"The weather in Florence, Italy is currently 40°C.","reasoning_content":"First, the user asked: \"What's the weather in Florence, Italy?\" This directly matches the available function \"weather\", which gets weather information for a location.\n\nThe function requires a \"location\" parameter, which is a string. The user provided \"Florence, Italy\", so all required parameters are present and clear. No need to ask for clarification.\n\nI should call the function using the specified JSON format within \u003cfunction_call\u003e tags. The format is: \u003cfunction_call\u003e{\"action\": \"function_name\", \"action_input\": {\"parameter\": \"argument\"}}\u003c/function_call\u003e\n\nSo, for this, it should be: \u003cfunction_call\u003e{\"action\": \"weather\", \"action_input\": {\"location\": \"Florence, Italy\"}}\u003c/function_call\u003e\n\nAfter calling the function, the response from the function is given as \"Function: 40 C\". This seems to be the result of the function call.\n\nNow, in my response as the assistant, I need to handle this. The system prompt says: \"You are a helpful assistant\" and I should respond based on the function call. Since I've made the function call, and now I have the result, I should provide a clear, non-verbose response to the user with the information.\n\nThe conversation is multi-turn, but in this case, the function call has been made, and I have the result. I need to present this result to the user.\n\nMy response should not be verbose, so I'll keep it concise. Something like: \"The weather in Florence, Italy is 40°C.\"\n\nThe function response is \"40 C\", which I assume means 40 degrees Celsius. I should make it user-friendly.\n\nFinally, ensure that I'm not making another function call unless needed. Here, the request is fulfilled with this information, so no need for further calls.\n\nResponse structure:\n- Since the function call was already made in the first response, now I need to provide the answer based on the function's output.","refusal":null,"role":"assistant","tool_calls":null},"stop_reason":null}],"created":1761842986,"id":"1792caed-512b-4e35-970a-614f14ed1aba_sidecar","model":"grok-3-mini-high","object":"chat.completion","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"usage":{"audio_prompt_tokens":0,"completion_tokens":12,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":394,"rejected_prediction_tokens":0},"num_sources_used":0,"prompt_tokens":332,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0,"image_tokens":0,"text_tokens":332},"total_tokens":738}}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.818933708s
diff --git a/internal/fantasy/providertests/testdata/TestAzureCommon/azure-grok-3-mini/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-grok-3-mini/tool_streaming.yaml
new file mode 100644
index 000000000..d53c5f7ec
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-grok-3-mini/tool_streaming.yaml
@@ -0,0 +1,1467 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 507
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"grok-3-mini","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}]}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"First","role":"assistant"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" asking"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" about"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" in"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Florence"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Italy"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" have"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" an"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" available"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" called"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"weather"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\""},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" that"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" can"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" get"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" information"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" for"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" location"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"The"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" description"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Get"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" information"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" for"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" location"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\"."},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" The"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameters"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" require"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"location"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\""},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" which"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" string"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" described"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" as"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"the"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" city"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\".\n\n"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"The"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" provided"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Florence"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Italy"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\"."},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" This"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" seems"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" specify"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" both"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" city"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" and"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" country"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" which"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" be"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" fine"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" for"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" location"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameter"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" The"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameter"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" described"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" as"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"the"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" city"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\","},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" but"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" it"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" doesn't"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" specify"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" that"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" it"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" must"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" be"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" just"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842989,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" city"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" name"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" without"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" country"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" In"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" practice"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" providing"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Florence"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Italy"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\""},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" help"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" dis"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"ambig"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"uate"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" if"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" there"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" are"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" multiple"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Flor"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"ences"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" so"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" it's"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" probably"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" acceptable"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"All"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" required"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameters"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" are"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" provided"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" location"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" given"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" as"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Florence"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Italy"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\"."},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" can"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" infer"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" that"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" this"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" be"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" passed"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" as"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" argument"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" for"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"location"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\""},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameter"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"The"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" instruction"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" says"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"If"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user's"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" query"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" can"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" be"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" addressed"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" using"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" an"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" available"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" and"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" all"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" required"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameters"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" are"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" provided"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" or"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" obviously"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" infer"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"able"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" trigger"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\""},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Here"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" matches"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" and"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameter"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" provided"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"I"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" in"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" specified"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" JSON"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" format"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" within"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \u003c"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"function"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"_call"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\u003e"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" tags"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"After"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" calling"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" if"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" needed"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" might"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" need"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" handle"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" in"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" subsequent"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" turns"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" but"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" for"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" now"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" this"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" logical"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" next"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" step"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"My"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" not"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" be"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" verbose"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":";"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" keep"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" it"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" clear"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" So"},"index":0}],"created":1761842990,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" shouldn't"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" add"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" extra"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" text"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" unless"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" necessary"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" The"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" instruction"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" says"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Keep"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" your"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" clear"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":";"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" please"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" do"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" not"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" make"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" your"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" verbose"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"!\""},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" And"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" only"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" use"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \u003c"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"function"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"_call"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\u003e"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" tag"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" if"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I'm"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" calling"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Since"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I'm"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" deciding"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" my"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" just"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" contain"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Final"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" decision"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Call"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" with"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" location"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" as"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Florence"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Italy"},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\"."},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"id":"call_78089033","index":0,"type":"function"}]},"index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{},"finish_reason":"tool_calls","index":0}],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[],"created":1761842991,"id":"39ac52a4-9d28-4208-a85e-044112b24910_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9","usage":{"completion_tokens":27,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":355,"rejected_prediction_tokens":0},"num_sources_used":0,"prompt_tokens":288,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0,"image_tokens":0,"text_tokens":288},"total_tokens":670}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 256.935666ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 727
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_78089033","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_78089033","role":"tool"}],"model":"grok-3-mini","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}]}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"First","role":"assistant"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" asked"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"What's"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" in"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Florence"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Italy"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"?\""},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" This"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" directly"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" matches"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" available"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"weather"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\","},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" which"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" requires"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"location"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\""},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameter"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"I"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" have"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" already"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" made"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" in"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" my"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" previous"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \u003c"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"function"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"_call"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\u003e{\""},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"action"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\":"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"weather"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\","},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"action"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"_input"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\":"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" {\""},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"location"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\":"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Florence"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Italy"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\""},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"}}\u003c/"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"function"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"_call"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\u003e."},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Now"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" system"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" has"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" provided"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" that"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Function"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" "},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"40"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" C"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\".\n\n"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"In"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" this"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" multi"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"-turn"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" conversation"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" need"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" continue"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" based"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" on"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"'s"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" The"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" was"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" successful"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" and"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" it"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" returned"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" information"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" as"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"40"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" C"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\","},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" which"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" assume"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" means"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" "},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"40"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" degrees"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Celsius"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"My"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" role"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" be"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" helpful"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" assistant"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" After"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" calling"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" provide"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" information"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" in"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" clear"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" and"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" non"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"-"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"verbose"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" way"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"The"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user's"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" request"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" now"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" fulfilled"},"index":0}],"created":1761842992,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" because"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" called"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" and"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" it"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" returned"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" data"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" don't"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" need"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" another"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" unless"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" more"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" required"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Guidelines"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":\n\n"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"-"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" If"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user's"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" request"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" fully"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" fulfilled"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" respond"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" with"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" information"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"-"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Keep"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" clear"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" and"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" not"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" verbose"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"-"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Only"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" use"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \u003c"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"function"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"_call"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\u003e"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" tags"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" if"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I'm"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" deciding"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" In"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" this"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" case"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" no"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" further"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" needed"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"So"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" now"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" respond"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" with"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" information"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" based"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" on"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"'s"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" output"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Response"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" structure"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":\n\n"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"-"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Be"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" direct"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"The"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" in"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Florence"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Italy"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" "},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"40"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"°C"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\"\n\n"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"I"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" confirm"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" units"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" The"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" returned"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"40"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" C"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\","},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" which"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" likely"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" means"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Celsius"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" but"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" be"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" precise"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I'll"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" assume"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" it's"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Celsius"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" as"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" it's"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" common"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" unit"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" for"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Finally"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" end"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" without"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" unnecessary"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" details"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"The"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" weather"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" in"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" Florence"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":","},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" Italy"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" is"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" "},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"40"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"°C"},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"."},"index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{},"finish_reason":"stop","index":0}],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[],"created":1761842993,"id":"a6f0c9ce-c6ec-45b2-9544-51b9dd3c2433_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9","usage":{"completion_tokens":11,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":328,"rejected_prediction_tokens":0},"num_sources_used":0,"prompt_tokens":332,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0,"image_tokens":0,"text_tokens":332},"total_tokens":671}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 410.234334ms
diff --git a/internal/fantasy/providertests/testdata/TestAzureCommon/azure-o4-mini/simple.yaml b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-o4-mini/simple.yaml
new file mode 100644
index 000000000..b7538fc96
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-o4-mini/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 168
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"o4-mini","max_completion_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 1203
+ body: |
+ {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"protected_material_code":{"filtered":false,"detected":false},"protected_material_text":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"finish_reason":"stop","index":0,"logprobs":null,"message":{"annotations":[],"content":"OlĆ”!","refusal":null,"role":"assistant"}}],"created":1761842947,"id":"chatcmpl-CWQ7f0bwWRBA8LDoImC3K2wezY8Ye","model":"o4-mini-2025-04-16","object":"chat.completion","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"system_fingerprint":null,"usage":{"completion_tokens":85,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":64,"rejected_prediction_tokens":0},"prompt_tokens":19,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":104}}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.380277667s
diff --git a/internal/fantasy/providertests/testdata/TestAzureCommon/azure-o4-mini/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-o4-mini/simple_streaming.yaml
new file mode 100644
index 000000000..22b2338fc
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-o4-mini/simple_streaming.yaml
@@ -0,0 +1,46 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 222
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"o4-mini","max_completion_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}]}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"content":"","refusal":null,"role":"assistant"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842949,"id":"chatcmpl-CWQ7hehqpDlf2niJw1ppNwUCBUH6W","model":"o4-mini-2025-04-16","obfuscation":"I","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"OlĆ”"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842949,"id":"chatcmpl-CWQ7hehqpDlf2niJw1ppNwUCBUH6W","model":"o4-mini-2025-04-16","obfuscation":"","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"!"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842949,"id":"chatcmpl-CWQ7hehqpDlf2niJw1ppNwUCBUH6W","model":"o4-mini-2025-04-16","obfuscation":"fH","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{},"finish_reason":"stop","index":0,"logprobs":null}],"created":1761842949,"id":"chatcmpl-CWQ7hehqpDlf2niJw1ppNwUCBUH6W","model":"o4-mini-2025-04-16","obfuscation":"p7EdA3UJmxdvk","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[],"created":1761842949,"id":"chatcmpl-CWQ7hehqpDlf2niJw1ppNwUCBUH6W","model":"o4-mini-2025-04-16","obfuscation":"","object":"chat.completion.chunk","system_fingerprint":null,"usage":{"completion_tokens":85,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":64,"rejected_prediction_tokens":0},"prompt_tokens":19,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":104}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.122837417s
diff --git a/internal/fantasy/providertests/testdata/TestAzureCommon/azure-o4-mini/tool.yaml b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-o4-mini/tool.yaml
new file mode 100644
index 000000000..92d21ee7f
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-o4-mini/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 460
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"o4-mini","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 1045
+ body: |
+ {"choices":[{"content_filter_results":{},"finish_reason":"tool_calls","index":0,"logprobs":null,"message":{"annotations":[],"content":null,"refusal":null,"role":"assistant","tool_calls":[{"function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"id":"call_tqngqwwVn8WQVUkgqtIYfoaH","type":"function"}]}}],"created":1761842950,"id":"chatcmpl-CWQ7i9yJPo9BpBFPBl73OgqhUtDVV","model":"o4-mini-2025-04-16","object":"chat.completion","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"system_fingerprint":null,"usage":{"completion_tokens":23,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens":64,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":87}}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.317917416s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 712
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_tqngqwwVn8WQVUkgqtIYfoaH","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_tqngqwwVn8WQVUkgqtIYfoaH","role":"tool"}],"model":"o4-mini","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 1249
+ body: |
+ {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"protected_material_code":{"filtered":false,"detected":false},"protected_material_text":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"finish_reason":"stop","index":0,"logprobs":null,"message":{"annotations":[],"content":"The current temperature in Florence, Italy is 40°C.","refusal":null,"role":"assistant"}}],"created":1761842951,"id":"chatcmpl-CWQ7jZUjKlLb6EssvJqOUYZ5uS4Nf","model":"o4-mini-2025-04-16","object":"chat.completion","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"system_fingerprint":null,"usage":{"completion_tokens":25,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens":92,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":117}}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 834.383375ms
diff --git a/internal/fantasy/providertests/testdata/TestAzureCommon/azure-o4-mini/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-o4-mini/tool_streaming.yaml
new file mode 100644
index 000000000..809616da2
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureCommon/azure-o4-mini/tool_streaming.yaml
@@ -0,0 +1,121 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 514
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"o4-mini","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}]}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"content":null,"refusal":null,"role":"assistant","tool_calls":[{"function":{"arguments":"","name":"weather"},"id":"call_9URIoTvgd5stQfgpr8dHAg9L","index":0,"type":"function"}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842952,"id":"chatcmpl-CWQ7kENkVMfDLAS6nHSmFXgbPVxi7","model":"o4-mini-2025-04-16","obfuscation":"","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"{\""},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842952,"id":"chatcmpl-CWQ7kENkVMfDLAS6nHSmFXgbPVxi7","model":"o4-mini-2025-04-16","obfuscation":"NCcJz9","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"location"},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842952,"id":"chatcmpl-CWQ7kENkVMfDLAS6nHSmFXgbPVxi7","model":"o4-mini-2025-04-16","obfuscation":"c","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"\":\""},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842952,"id":"chatcmpl-CWQ7kENkVMfDLAS6nHSmFXgbPVxi7","model":"o4-mini-2025-04-16","obfuscation":"59wG","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"Flor"},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842952,"id":"chatcmpl-CWQ7kENkVMfDLAS6nHSmFXgbPVxi7","model":"o4-mini-2025-04-16","obfuscation":"vBcyl","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"ence"},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842952,"id":"chatcmpl-CWQ7kENkVMfDLAS6nHSmFXgbPVxi7","model":"o4-mini-2025-04-16","obfuscation":"pIOsj","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":","},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842952,"id":"chatcmpl-CWQ7kENkVMfDLAS6nHSmFXgbPVxi7","model":"o4-mini-2025-04-16","obfuscation":"0Nhjk7XH","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"Italy"},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842952,"id":"chatcmpl-CWQ7kENkVMfDLAS6nHSmFXgbPVxi7","model":"o4-mini-2025-04-16","obfuscation":"kI4T","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"\"}"},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842952,"id":"chatcmpl-CWQ7kENkVMfDLAS6nHSmFXgbPVxi7","model":"o4-mini-2025-04-16","obfuscation":"e8PzDD","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{},"finish_reason":"tool_calls","index":0,"logprobs":null}],"created":1761842952,"id":"chatcmpl-CWQ7kENkVMfDLAS6nHSmFXgbPVxi7","model":"o4-mini-2025-04-16","obfuscation":"BXRFyNp","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[],"created":1761842952,"id":"chatcmpl-CWQ7kENkVMfDLAS6nHSmFXgbPVxi7","model":"o4-mini-2025-04-16","obfuscation":"4Z","object":"chat.completion.chunk","system_fingerprint":null,"usage":{"completion_tokens":23,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens":64,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":87}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 980.975375ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 765
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_9URIoTvgd5stQfgpr8dHAg9L","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_9URIoTvgd5stQfgpr8dHAg9L","role":"tool"}],"model":"o4-mini","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}]}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"content":"","refusal":null,"role":"assistant"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842953,"id":"chatcmpl-CWQ7lsQr88iejRMbeEhyd871OqpiJ","model":"o4-mini-2025-04-16","obfuscation":"6","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"The"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842953,"id":"chatcmpl-CWQ7lsQr88iejRMbeEhyd871OqpiJ","model":"o4-mini-2025-04-16","obfuscation":"","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" current"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842953,"id":"chatcmpl-CWQ7lsQr88iejRMbeEhyd871OqpiJ","model":"o4-mini-2025-04-16","obfuscation":"hUDX8HnCTVS","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" temperature"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842953,"id":"chatcmpl-CWQ7lsQr88iejRMbeEhyd871OqpiJ","model":"o4-mini-2025-04-16","obfuscation":"mwMYc2I","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" in"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842953,"id":"chatcmpl-CWQ7lsQr88iejRMbeEhyd871OqpiJ","model":"o4-mini-2025-04-16","obfuscation":"","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" Florence"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842953,"id":"chatcmpl-CWQ7lsQr88iejRMbeEhyd871OqpiJ","model":"o4-mini-2025-04-16","obfuscation":"uk82d5NseJ","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":","},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842953,"id":"chatcmpl-CWQ7lsQr88iejRMbeEhyd871OqpiJ","model":"o4-mini-2025-04-16","obfuscation":"gH","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" Italy"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842953,"id":"chatcmpl-CWQ7lsQr88iejRMbeEhyd871OqpiJ","model":"o4-mini-2025-04-16","obfuscation":"tCtxzaNt6jg7V","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" is"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842953,"id":"chatcmpl-CWQ7lsQr88iejRMbeEhyd871OqpiJ","model":"o4-mini-2025-04-16","obfuscation":"","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" "},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842953,"id":"chatcmpl-CWQ7lsQr88iejRMbeEhyd871OqpiJ","model":"o4-mini-2025-04-16","obfuscation":"Kk","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"40"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842953,"id":"chatcmpl-CWQ7lsQr88iejRMbeEhyd871OqpiJ","model":"o4-mini-2025-04-16","obfuscation":"m","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"°C"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842953,"id":"chatcmpl-CWQ7lsQr88iejRMbeEhyd871OqpiJ","model":"o4-mini-2025-04-16","obfuscation":"v","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"."},"finish_reason":null,"index":0,"logprobs":null}],"created":1761842953,"id":"chatcmpl-CWQ7lsQr88iejRMbeEhyd871OqpiJ","model":"o4-mini-2025-04-16","obfuscation":"rm","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{},"finish_reason":"stop","index":0,"logprobs":null}],"created":1761842953,"id":"chatcmpl-CWQ7lsQr88iejRMbeEhyd871OqpiJ","model":"o4-mini-2025-04-16","obfuscation":"psinnxINFfODK","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[],"created":1761842953,"id":"chatcmpl-CWQ7lsQr88iejRMbeEhyd871OqpiJ","model":"o4-mini-2025-04-16","obfuscation":"9","object":"chat.completion.chunk","system_fingerprint":null,"usage":{"completion_tokens":25,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens":92,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":117}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 375.330583ms
diff --git a/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-gpt-5-mini/simple.yaml b/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-gpt-5-mini/simple.yaml
new file mode 100644
index 000000000..035f7d044
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-gpt-5-mini/simple.yaml
@@ -0,0 +1,102 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 212
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"Say hi in Portuguese","type":"input_text"}],"role":"user"}],"model":"gpt-5-mini"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 1559
+ body: |-
+ {
+ "id": "resp_099c69d9f7a8450501690399717e048194a086be1ecd3178eb",
+ "object": "response",
+ "created_at": 1761843569,
+ "status": "completed",
+ "background": false,
+ "content_filters": null,
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-5-mini",
+ "output": [
+ {
+ "id": "rs_099c69d9f7a845050169039971fb208194884ced01a08fdfd6",
+ "type": "reasoning",
+ "summary": []
+ },
+ {
+ "id": "msg_099c69d9f7a8450501690399758a5081948d95d3d1560ba719",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "Ol\u00e1! (Tamb\u00e9m pode dizer \"Oi!\")"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 19,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 143,
+ "output_tokens_details": {
+ "reasoning_tokens": 128
+ },
+ "total_tokens": 162
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 6.221231041s
diff --git a/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-gpt-5-mini/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-gpt-5-mini/simple_streaming.yaml
new file mode 100644
index 000000000..be0f91636
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-gpt-5-mini/simple_streaming.yaml
@@ -0,0 +1,68 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 226
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"Say hi in Portuguese","type":"input_text"}],"role":"user"}],"model":"gpt-5-mini","stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0b4726240aaacbdc0169039977006081968d5b3074ea5b42a1","object":"response","created_at":1761843575,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-mini","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0b4726240aaacbdc0169039977006081968d5b3074ea5b42a1","object":"response","created_at":1761843575,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-mini","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_0b4726240aaacbdc01690399775ac8819687e64c00134959bd","type":"reasoning","summary":[]}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_0b4726240aaacbdc01690399775ac8819687e64c00134959bd","type":"reasoning","summary":[]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"msg_0b4726240aaacbdc01690399791ef48196a80844dabf0c19d1","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":5,"item_id":"msg_0b4726240aaacbdc01690399791ef48196a80844dabf0c19d1","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_0b4726240aaacbdc01690399791ef48196a80844dabf0c19d1","output_index":1,"content_index":0,"delta":"OlĆ”","logprobs":[],"obfuscation":"GnLMSVqNdNbj1"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_0b4726240aaacbdc01690399791ef48196a80844dabf0c19d1","output_index":1,"content_index":0,"delta":"!","logprobs":[],"obfuscation":"qkamnZvkApJNl5A"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":8,"item_id":"msg_0b4726240aaacbdc01690399791ef48196a80844dabf0c19d1","output_index":1,"content_index":0,"text":"OlĆ”!","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":9,"item_id":"msg_0b4726240aaacbdc01690399791ef48196a80844dabf0c19d1","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"OlĆ”!"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":10,"output_index":1,"item":{"id":"msg_0b4726240aaacbdc01690399791ef48196a80844dabf0c19d1","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"OlĆ”!"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":11,"response":{"id":"resp_0b4726240aaacbdc0169039977006081968d5b3074ea5b42a1","object":"response","created_at":1761843575,"status":"completed","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-mini","output":[{"id":"rs_0b4726240aaacbdc01690399775ac8819687e64c00134959bd","type":"reasoning","summary":[]},{"id":"msg_0b4726240aaacbdc01690399791ef48196a80844dabf0c19d1","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"OlĆ”!"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":19,"input_tokens_details":{"cached_tokens":0},"output_tokens":72,"output_tokens_details":{"reasoning_tokens":64},"total_tokens":91},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 170.893459ms
diff --git a/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-gpt-5-mini/tool.yaml b/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-gpt-5-mini/tool.yaml
new file mode 100644
index 000000000..e78acefcc
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-gpt-5-mini/tool.yaml
@@ -0,0 +1,233 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 491
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"}],"model":"gpt-5-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 1866
+ body: |-
+ {
+ "id": "resp_01ac948c31d692b30169039979ab2c819096befaa857fd6bd5",
+ "object": "response",
+ "created_at": 1761843577,
+ "status": "completed",
+ "background": false,
+ "content_filters": null,
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-5-mini",
+ "output": [
+ {
+ "id": "rs_01ac948c31d692b3016903997a0748819094955c49dc9168e3",
+ "type": "reasoning",
+ "summary": []
+ },
+ {
+ "id": "fc_01ac948c31d692b3016903997b1a648190b3e9f6259464edf9",
+ "type": "function_call",
+ "status": "completed",
+ "arguments": "{\"location\":\"Florence, Italy\"}",
+ "call_id": "call_4aipZJRtNzKfQ9VlnBGhI9zH",
+ "name": "weather"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 63,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 22,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 85
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.717185959s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 726
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_4aipZJRtNzKfQ9VlnBGhI9zH","name":"weather","type":"function_call"},{"call_id":"call_4aipZJRtNzKfQ9VlnBGhI9zH","output":"40 C","type":"function_call_output"}],"model":"gpt-5-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 2085
+ body: |-
+ {
+ "id": "resp_066ab1dbe82e48a5016903997c6398819681f9e88196773871",
+ "object": "response",
+ "created_at": 1761843580,
+ "status": "completed",
+ "background": false,
+ "content_filters": null,
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-5-mini",
+ "output": [
+ {
+ "id": "rs_066ab1dbe82e48a5016903997cc74c8196add4b9db1dde2dfb",
+ "type": "reasoning",
+ "summary": []
+ },
+ {
+ "id": "msg_066ab1dbe82e48a5016903997ec4dc81968c78c2634a2d1a89",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "Current temperature in Florence, Italy: 40\u00b0C (104\u00b0F).\n\nWant more details (hourly forecast, wind, precipitation) or tips for staying comfortable in the heat?"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 94,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 169,
+ "output_tokens_details": {
+ "reasoning_tokens": 128
+ },
+ "total_tokens": 263
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.237920417s
diff --git a/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-gpt-5-mini/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-gpt-5-mini/tool_streaming.yaml
new file mode 100644
index 000000000..ed9d4b66a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-gpt-5-mini/tool_streaming.yaml
@@ -0,0 +1,331 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 505
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"}],"model":"gpt-5-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0ad1ae6a186e7452016903997fa0d8819789788f2c97870a47","object":"response","created_at":1761843583,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-mini","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0ad1ae6a186e7452016903997fa0d8819789788f2c97870a47","object":"response","created_at":1761843583,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-mini","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_0ad1ae6a186e745201690399806f4881978af5b1fc084f306e","type":"reasoning","summary":[]}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_0ad1ae6a186e745201690399806f4881978af5b1fc084f306e","type":"reasoning","summary":[]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"fc_0ad1ae6a186e7452016903998145b481978147edc29c8250c0","type":"function_call","status":"in_progress","arguments":"","call_id":"call_mamm0WNokaTJlgAO8uAxyWBM","name":"weather"}}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":5,"item_id":"fc_0ad1ae6a186e7452016903998145b481978147edc29c8250c0","output_index":1,"delta":"{\"","obfuscation":"xb8TNAoGrlJ8OT"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":6,"item_id":"fc_0ad1ae6a186e7452016903998145b481978147edc29c8250c0","output_index":1,"delta":"location","obfuscation":"mEUXsnjk"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":7,"item_id":"fc_0ad1ae6a186e7452016903998145b481978147edc29c8250c0","output_index":1,"delta":"\":\"","obfuscation":"PvVSvDVCLTqCk"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":8,"item_id":"fc_0ad1ae6a186e7452016903998145b481978147edc29c8250c0","output_index":1,"delta":"Flor","obfuscation":"hL40UicR3y1J"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":9,"item_id":"fc_0ad1ae6a186e7452016903998145b481978147edc29c8250c0","output_index":1,"delta":"ence","obfuscation":"VE9oDPOnNhBm"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":10,"item_id":"fc_0ad1ae6a186e7452016903998145b481978147edc29c8250c0","output_index":1,"delta":",","obfuscation":"KpJCoI7GvdKtRCj"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":11,"item_id":"fc_0ad1ae6a186e7452016903998145b481978147edc29c8250c0","output_index":1,"delta":" Italy","obfuscation":"CJ8iSJ4Jbl"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":12,"item_id":"fc_0ad1ae6a186e7452016903998145b481978147edc29c8250c0","output_index":1,"delta":"\"}","obfuscation":"F9cJQt3WOkhsmL"}
+
+ event: response.function_call_arguments.done
+ data: {"type":"response.function_call_arguments.done","sequence_number":13,"item_id":"fc_0ad1ae6a186e7452016903998145b481978147edc29c8250c0","output_index":1,"arguments":"{\"location\":\"Florence, Italy\"}"}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":14,"output_index":1,"item":{"id":"fc_0ad1ae6a186e7452016903998145b481978147edc29c8250c0","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence, Italy\"}","call_id":"call_mamm0WNokaTJlgAO8uAxyWBM","name":"weather"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":15,"response":{"id":"resp_0ad1ae6a186e7452016903997fa0d8819789788f2c97870a47","object":"response","created_at":1761843583,"status":"completed","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-mini","output":[{"id":"rs_0ad1ae6a186e745201690399806f4881978af5b1fc084f306e","type":"reasoning","summary":[]},{"id":"fc_0ad1ae6a186e7452016903998145b481978147edc29c8250c0","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence, Italy\"}","call_id":"call_mamm0WNokaTJlgAO8uAxyWBM","name":"weather"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":63,"input_tokens_details":{"cached_tokens":0},"output_tokens":22,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":85},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 177.438666ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 740
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_mamm0WNokaTJlgAO8uAxyWBM","name":"weather","type":"function_call"},{"call_id":"call_mamm0WNokaTJlgAO8uAxyWBM","output":"40 C","type":"function_call_output"}],"model":"gpt-5-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0669ae4cb293f3580169039981d420819480db231cc8663959","object":"response","created_at":1761843585,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-mini","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0669ae4cb293f3580169039981d420819480db231cc8663959","object":"response","created_at":1761843585,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-mini","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_0669ae4cb293f358016903998223508194a9c3ccc4d2add0f5","type":"reasoning","summary":[]}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_0669ae4cb293f358016903998223508194a9c3ccc4d2add0f5","type":"reasoning","summary":[]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":5,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":"Current","logprobs":[],"obfuscation":"YUXg8Iykd"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" temperature","logprobs":[],"obfuscation":"bb6P"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"FeqbqaQiPmHUL"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" Florence","logprobs":[],"obfuscation":"SuoIGqz"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":",","logprobs":[],"obfuscation":"Ij5SSzCgmFlpNav"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" Italy","logprobs":[],"obfuscation":"KTJd3yowio"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":":","logprobs":[],"obfuscation":"Bth9GzcDaKwGnO6"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"MkRBoOMGDR2MDvu"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":"40","logprobs":[],"obfuscation":"6YIYL3RxP4wi84"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" °","logprobs":[],"obfuscation":"QiyhSnnmc5fveG"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":"C","logprobs":[],"obfuscation":"8nqRSost8IdQK1f"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" (","logprobs":[],"obfuscation":"i0gTfMDJ3tzflB"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":"104","logprobs":[],"obfuscation":"dRcfQEBeWLZkR"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" °","logprobs":[],"obfuscation":"eqfOyurzyhXwEJ"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":"F","logprobs":[],"obfuscation":"CCLNJEgnIT3faMo"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":").\n\n","logprobs":[],"obfuscation":"5Ev3L4gxcaTf"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":"That","logprobs":[],"obfuscation":"pEHQpfcwnAQa"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":"ās","logprobs":[],"obfuscation":"JjWl4Vx4cbvJPO"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" very","logprobs":[],"obfuscation":"Gv3mTfCKlM3"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" hot","logprobs":[],"obfuscation":"lD2UZCEai5kb"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" ā","logprobs":[],"obfuscation":"3XSNtZmk5iyS08"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" take","logprobs":[],"obfuscation":"lJJwESHK5Ao"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" precautions","logprobs":[],"obfuscation":"l8pP"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":29,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":":","logprobs":[],"obfuscation":"c3XL2U4knYVRArf"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":30,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" stay","logprobs":[],"obfuscation":"fB0L7HvKblC"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":31,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" hydrated","logprobs":[],"obfuscation":"spMOCpO"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":32,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":",","logprobs":[],"obfuscation":"ZxSlxARmWPSVdc8"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":33,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" avoid","logprobs":[],"obfuscation":"O2EJrU5sCo"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":34,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" strenuous","logprobs":[],"obfuscation":"VXHTVr"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":35,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" outdoor","logprobs":[],"obfuscation":"u5dtEeU5"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":36,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" activity","logprobs":[],"obfuscation":"U7n4V9d"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":37,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"jlBszwOVTi1yG"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":38,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" midday","logprobs":[],"obfuscation":"LjlKH4TQI"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":39,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":",","logprobs":[],"obfuscation":"Q75aa2MRW4Wl0B1"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":40,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" wear","logprobs":[],"obfuscation":"ik5eRNe9wzL"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":41,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" light","logprobs":[],"obfuscation":"X56lfgK7TN"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":42,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" clothing","logprobs":[],"obfuscation":"AEdkYDW"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":43,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" and","logprobs":[],"obfuscation":"gXRfAUZBv7eM"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":44,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" sunscreen","logprobs":[],"obfuscation":"ONc8XR"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":45,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":",","logprobs":[],"obfuscation":"i5WC6SGVLHdxpww"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":46,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" and","logprobs":[],"obfuscation":"jTn5XtOyMo4X"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":47,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" seek","logprobs":[],"obfuscation":"A7MMXUstGyx"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":48,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" air","logprobs":[],"obfuscation":"jBAmIqPdajUP"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":49,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" conditioning","logprobs":[],"obfuscation":"7GT"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":50,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"zkO36wHibZmTy"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":51,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" shade","logprobs":[],"obfuscation":"r08FUDYRX3"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":52,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":".","logprobs":[],"obfuscation":"8WL1k4gCr7hWiYw"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":53,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" Would","logprobs":[],"obfuscation":"mjl5Gax8B3"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":54,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" you","logprobs":[],"obfuscation":"wdtJg7Nb4BsT"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":55,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" like","logprobs":[],"obfuscation":"fTc3TdwAIfP"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":56,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" humidity","logprobs":[],"obfuscation":"z8rpQqw"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":57,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":",","logprobs":[],"obfuscation":"oMgy9Qqsy17fXPp"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":58,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" wind","logprobs":[],"obfuscation":"4UxXmyaM3Fg"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":59,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":",","logprobs":[],"obfuscation":"griV0t18AuG48ck"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":60,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" an","logprobs":[],"obfuscation":"SnqvPe56Ff9aw"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":61,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" hourly","logprobs":[],"obfuscation":"DevE7UbrP"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":62,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" forecast","logprobs":[],"obfuscation":"MBXAMAs"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":63,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":",","logprobs":[],"obfuscation":"DkZwaJROGaET5qh"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":64,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"43HaF6XpEzWD8"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":65,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" a","logprobs":[],"obfuscation":"ZMolZAo8kHNhby"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":66,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" multi","logprobs":[],"obfuscation":"Lj4eJPPIQx"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":67,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":"-day","logprobs":[],"obfuscation":"d6jZ36RZnrpX"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":68,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":" outlook","logprobs":[],"obfuscation":"rMzbH7f9"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":69,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"delta":"?","logprobs":[],"obfuscation":"5HInlxq1zrPSPMx"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":70,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"text":"Current temperature in Florence, Italy: 40 °C (104 °F).\n\nThatās very hot ā take precautions: stay hydrated, avoid strenuous outdoor activity in midday, wear light clothing and sunscreen, and seek air conditioning or shade. Would you like humidity, wind, an hourly forecast, or a multi-day outlook?","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":71,"item_id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"Current temperature in Florence, Italy: 40 °C (104 °F).\n\nThatās very hot ā take precautions: stay hydrated, avoid strenuous outdoor activity in midday, wear light clothing and sunscreen, and seek air conditioning or shade. Would you like humidity, wind, an hourly forecast, or a multi-day outlook?"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":72,"output_index":1,"item":{"id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"Current temperature in Florence, Italy: 40 °C (104 °F).\n\nThatās very hot ā take precautions: stay hydrated, avoid strenuous outdoor activity in midday, wear light clothing and sunscreen, and seek air conditioning or shade. Would you like humidity, wind, an hourly forecast, or a multi-day outlook?"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":73,"response":{"id":"resp_0669ae4cb293f3580169039981d420819480db231cc8663959","object":"response","created_at":1761843585,"status":"completed","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-mini","output":[{"id":"rs_0669ae4cb293f358016903998223508194a9c3ccc4d2add0f5","type":"reasoning","summary":[]},{"id":"msg_0669ae4cb293f3580169039985fa088194875995735ecbd2d4","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"Current temperature in Florence, Italy: 40 °C (104 °F).\n\nThatās very hot ā take precautions: stay hydrated, avoid strenuous outdoor activity in midday, wear light clothing and sunscreen, and seek air conditioning or shade. Would you like humidity, wind, an hourly forecast, or a multi-day outlook?"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":94,"input_tokens_details":{"cached_tokens":0},"output_tokens":262,"output_tokens_details":{"reasoning_tokens":192},"total_tokens":356},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 184.712542ms
diff --git a/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-o4-mini/simple.yaml b/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-o4-mini/simple.yaml
new file mode 100644
index 000000000..eb9203483
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-o4-mini/simple.yaml
@@ -0,0 +1,102 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 209
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"Say hi in Portuguese","type":"input_text"}],"role":"user"}],"model":"o4-mini"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 1520
+ body: |-
+ {
+ "id": "resp_056c26e70a8e16d60169039987a9748195bc77169735bc7b98",
+ "object": "response",
+ "created_at": 1761843591,
+ "status": "completed",
+ "background": false,
+ "content_filters": null,
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "o4-mini",
+ "output": [
+ {
+ "id": "rs_056c26e70a8e16d601690399881f0c8195aa22699fa3be5974",
+ "type": "reasoning",
+ "summary": []
+ },
+ {
+ "id": "msg_056c26e70a8e16d601690399893da08195a98d7b4b749fcfe4",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "Ol\u00e1!"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 19,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 72,
+ "output_tokens_details": {
+ "reasoning_tokens": 64
+ },
+ "total_tokens": 91
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.899735709s
diff --git a/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-o4-mini/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-o4-mini/simple_streaming.yaml
new file mode 100644
index 000000000..6093d80d2
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-o4-mini/simple_streaming.yaml
@@ -0,0 +1,68 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 223
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"Say hi in Portuguese","type":"input_text"}],"role":"user"}],"model":"o4-mini","stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_091bc858adb4a712016903998991688197a893284934f22beb","object":"response","created_at":1761843593,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_091bc858adb4a712016903998991688197a893284934f22beb","object":"response","created_at":1761843593,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_091bc858adb4a7120169039989ef448197b309436b1aa244e7","type":"reasoning","summary":[]}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_091bc858adb4a7120169039989ef448197b309436b1aa244e7","type":"reasoning","summary":[]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"msg_091bc858adb4a712016903998a8ecc8197a424735435352dc2","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":5,"item_id":"msg_091bc858adb4a712016903998a8ecc8197a424735435352dc2","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_091bc858adb4a712016903998a8ecc8197a424735435352dc2","output_index":1,"content_index":0,"delta":"Oi","logprobs":[],"obfuscation":"d1QayNRkhDJkTu"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_091bc858adb4a712016903998a8ecc8197a424735435352dc2","output_index":1,"content_index":0,"delta":"!","logprobs":[],"obfuscation":"jSyFniBbtoZb0gy"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":8,"item_id":"msg_091bc858adb4a712016903998a8ecc8197a424735435352dc2","output_index":1,"content_index":0,"text":"Oi!","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":9,"item_id":"msg_091bc858adb4a712016903998a8ecc8197a424735435352dc2","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"Oi!"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":10,"output_index":1,"item":{"id":"msg_091bc858adb4a712016903998a8ecc8197a424735435352dc2","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"Oi!"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":11,"response":{"id":"resp_091bc858adb4a712016903998991688197a893284934f22beb","object":"response","created_at":1761843593,"status":"completed","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini","output":[{"id":"rs_091bc858adb4a7120169039989ef448197b309436b1aa244e7","type":"reasoning","summary":[]},{"id":"msg_091bc858adb4a712016903998a8ecc8197a424735435352dc2","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"Oi!"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":19,"input_tokens_details":{"cached_tokens":0},"output_tokens":8,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":27},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 174.388291ms
diff --git a/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-o4-mini/tool.yaml b/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-o4-mini/tool.yaml
new file mode 100644
index 000000000..aca5060eb
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-o4-mini/tool.yaml
@@ -0,0 +1,233 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 488
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"}],"model":"o4-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 1865
+ body: |-
+ {
+ "id": "resp_0459c9bec5645f0d016903998adb588197a8cb12bdc148c0a5",
+ "object": "response",
+ "created_at": 1761843594,
+ "status": "completed",
+ "background": false,
+ "content_filters": null,
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "o4-mini",
+ "output": [
+ {
+ "id": "rs_0459c9bec5645f0d016903998b51ec819785c9c9da0ebeec48",
+ "type": "reasoning",
+ "summary": []
+ },
+ {
+ "id": "fc_0459c9bec5645f0d016903998c5314819785e0c10f576a252d",
+ "type": "function_call",
+ "status": "completed",
+ "arguments": "{\"location\":\"Florence, Italy\"}",
+ "call_id": "call_KsHVstPJ9P9QHZsBVz58GUc6",
+ "name": "weather"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 60,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 83,
+ "output_tokens_details": {
+ "reasoning_tokens": 64
+ },
+ "total_tokens": 143
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.805354834s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 723
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_KsHVstPJ9P9QHZsBVz58GUc6","name":"weather","type":"function_call"},{"call_id":"call_KsHVstPJ9P9QHZsBVz58GUc6","output":"40 C","type":"function_call_output"}],"model":"o4-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 2111
+ body: |-
+ {
+ "id": "resp_087bd2312c2d3baa016903998caab081959b29b07fd8007b50",
+ "object": "response",
+ "created_at": 1761843596,
+ "status": "completed",
+ "background": false,
+ "content_filters": null,
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "o4-mini",
+ "output": [
+ {
+ "id": "rs_087bd2312c2d3baa016903998d0c088195808061e1055e926d",
+ "type": "reasoning",
+ "summary": []
+ },
+ {
+ "id": "msg_087bd2312c2d3baa016903998efbd48195b7dd1b75dcad44c6",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "The current temperature in Florence, Italy is 40 \u00b0C. It\u2019s quite hot\u2014make sure to stay hydrated, seek shade when you can, and limit prolonged sun exposure if you\u2019re out and about."
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 91,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 112,
+ "output_tokens_details": {
+ "reasoning_tokens": 64
+ },
+ "total_tokens": 203
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.146838417s
diff --git a/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-o4-mini/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-o4-mini/tool_streaming.yaml
new file mode 100644
index 000000000..b9addb495
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureResponsesCommon/azure-o4-mini/tool_streaming.yaml
@@ -0,0 +1,250 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 502
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"}],"model":"o4-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0b7f08ced9d9d7bd016903998fd1908196895bd1c221f34e18","object":"response","created_at":1761843599,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0b7f08ced9d9d7bd016903998fd1908196895bd1c221f34e18","object":"response","created_at":1761843599,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_0b7f08ced9d9d7bd01690399902bb48196b17ce126fbf2111e","type":"reasoning","summary":[]}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_0b7f08ced9d9d7bd01690399902bb48196b17ce126fbf2111e","type":"reasoning","summary":[]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"fc_0b7f08ced9d9d7bd0169039990be8481969746d4045d21c266","type":"function_call","status":"in_progress","arguments":"","call_id":"call_JJ5rFdfdpHh9ZJy19XQegVfz","name":"weather"}}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":5,"item_id":"fc_0b7f08ced9d9d7bd0169039990be8481969746d4045d21c266","output_index":1,"delta":"{\"","obfuscation":"cgjpCLpTcB9Zf2"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":6,"item_id":"fc_0b7f08ced9d9d7bd0169039990be8481969746d4045d21c266","output_index":1,"delta":"location","obfuscation":"XPmmF00x"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":7,"item_id":"fc_0b7f08ced9d9d7bd0169039990be8481969746d4045d21c266","output_index":1,"delta":"\":\"","obfuscation":"DUBg9hoAsCbE6"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":8,"item_id":"fc_0b7f08ced9d9d7bd0169039990be8481969746d4045d21c266","output_index":1,"delta":"Flor","obfuscation":"VpK5lvyLsltv"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":9,"item_id":"fc_0b7f08ced9d9d7bd0169039990be8481969746d4045d21c266","output_index":1,"delta":"ence","obfuscation":"0XKHIXG3tLBQ"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":10,"item_id":"fc_0b7f08ced9d9d7bd0169039990be8481969746d4045d21c266","output_index":1,"delta":",","obfuscation":"n4lnmQ8LR667bXP"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":11,"item_id":"fc_0b7f08ced9d9d7bd0169039990be8481969746d4045d21c266","output_index":1,"delta":" Italy","obfuscation":"M0QDr2aViB"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":12,"item_id":"fc_0b7f08ced9d9d7bd0169039990be8481969746d4045d21c266","output_index":1,"delta":"\"}","obfuscation":"c3YC6xIH7lcYjT"}
+
+ event: response.function_call_arguments.done
+ data: {"type":"response.function_call_arguments.done","sequence_number":13,"item_id":"fc_0b7f08ced9d9d7bd0169039990be8481969746d4045d21c266","output_index":1,"arguments":"{\"location\":\"Florence, Italy\"}"}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":14,"output_index":1,"item":{"id":"fc_0b7f08ced9d9d7bd0169039990be8481969746d4045d21c266","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence, Italy\"}","call_id":"call_JJ5rFdfdpHh9ZJy19XQegVfz","name":"weather"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":15,"response":{"id":"resp_0b7f08ced9d9d7bd016903998fd1908196895bd1c221f34e18","object":"response","created_at":1761843599,"status":"completed","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini","output":[{"id":"rs_0b7f08ced9d9d7bd01690399902bb48196b17ce126fbf2111e","type":"reasoning","summary":[]},{"id":"fc_0b7f08ced9d9d7bd0169039990be8481969746d4045d21c266","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence, Italy\"}","call_id":"call_JJ5rFdfdpHh9ZJy19XQegVfz","name":"weather"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":60,"input_tokens_details":{"cached_tokens":0},"output_tokens":19,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":79},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 182.661166ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 737
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_JJ5rFdfdpHh9ZJy19XQegVfz","name":"weather","type":"function_call"},{"call_id":"call_JJ5rFdfdpHh9ZJy19XQegVfz","output":"40 C","type":"function_call_output"}],"model":"o4-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_011b2d0f6a78b665016903999115ec819099779a1d80618d98","object":"response","created_at":1761843601,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_011b2d0f6a78b665016903999115ec819099779a1d80618d98","object":"response","created_at":1761843601,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"upQlXZ1sxNPrl"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" current","logprobs":[],"obfuscation":"aSzbaG8e"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" temperature","logprobs":[],"obfuscation":"50XM"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"ryo5epJwpylEV"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" Florence","logprobs":[],"obfuscation":"aKlVZgp"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"ZYEhjo7ByuNpzcu"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" Italy","logprobs":[],"obfuscation":"8BAYTNuT4p"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"ajjWYDwbpiHbs"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"g7ktsmII0tXJGG5"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":"40","logprobs":[],"obfuscation":"6FK8Wcqq10DCmB"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":"°C","logprobs":[],"obfuscation":"ir6Yd3qwQEt7s9"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"JthgyWnlKLjRxlO"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" It","logprobs":[],"obfuscation":"6UmRpKmTQsoOz"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":"ās","logprobs":[],"obfuscation":"A3Yl5GKGGyYKHG"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" quite","logprobs":[],"obfuscation":"C4NGZPVBW2"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" hot","logprobs":[],"obfuscation":"im74MTKbKvre"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"xpP4ecr8NPPdvF9"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" so","logprobs":[],"obfuscation":"0gVvoMqsB57mm"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" you","logprobs":[],"obfuscation":"QeH6z885stmw"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" may","logprobs":[],"obfuscation":"yzmAT5Opdade"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" want","logprobs":[],"obfuscation":"YnVuSooqWAJ"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" to","logprobs":[],"obfuscation":"EfFNHydyBNMfe"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" stay","logprobs":[],"obfuscation":"NP35x6gPd7x"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" hydrated","logprobs":[],"obfuscation":"BvX5LCw"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"5wcbwriUGbmSmUU"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":29,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" wear","logprobs":[],"obfuscation":"1rxRb2COyGo"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":30,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" light","logprobs":[],"obfuscation":"up3raT1fLS"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":31,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" clothing","logprobs":[],"obfuscation":"YJGqtvy"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":32,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"iTxRJkB46mLuiUM"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":33,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" and","logprobs":[],"obfuscation":"xq1m1FLe7YXL"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":34,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" seek","logprobs":[],"obfuscation":"drb00voTDEa"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":35,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" shade","logprobs":[],"obfuscation":"YeAZdx1N7d"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":36,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"RTj2UdDZAa9TL"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":37,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" air","logprobs":[],"obfuscation":"K39V5Cqf1MfT"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":38,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":"-conditioned","logprobs":[],"obfuscation":"pAYl"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":39,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" spaces","logprobs":[],"obfuscation":"XrtLgvxDI"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":40,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" when","logprobs":[],"obfuscation":"T7LUeJRYRuu"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":41,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":" possible","logprobs":[],"obfuscation":"6rU23jI"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":42,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"Dr0TXhpKpU4Dccf"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":43,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"text":"The current temperature in Florence, Italy is 40°C. Itās quite hot, so you may want to stay hydrated, wear light clothing, and seek shade or air-conditioned spaces when possible.","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":44,"item_id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"The current temperature in Florence, Italy is 40°C. Itās quite hot, so you may want to stay hydrated, wear light clothing, and seek shade or air-conditioned spaces when possible."}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":45,"output_index":0,"item":{"id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current temperature in Florence, Italy is 40°C. Itās quite hot, so you may want to stay hydrated, wear light clothing, and seek shade or air-conditioned spaces when possible."}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":46,"response":{"id":"resp_011b2d0f6a78b665016903999115ec819099779a1d80618d98","object":"response","created_at":1761843601,"status":"completed","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini","output":[{"id":"msg_011b2d0f6a78b6650169039991fff08190bfc35efd03edd318","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current temperature in Florence, Italy is 40°C. Itās quite hot, so you may want to stay hydrated, wear light clothing, and seek shade or air-conditioned spaces when possible."}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":91,"input_tokens_details":{"cached_tokens":0},"output_tokens":43,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":134},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 182.018917ms
diff --git a/internal/fantasy/providertests/testdata/TestAzureResponsesWithSummaryThinking/azure-gpt-5-mini/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestAzureResponsesWithSummaryThinking/azure-gpt-5-mini/thinking-streaming.yaml
new file mode 100644
index 000000000..718a3901b
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureResponsesWithSummaryThinking/azure-gpt-5-mini/thinking-streaming.yaml
@@ -0,0 +1,1198 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 570
+ host: ""
+ body: '{"store":false,"include":["reasoning.encrypted_content"],"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence, Italy?","type":"input_text"}],"role":"user"}],"model":"gpt-5-mini","reasoning":{"effort":"high","summary":"auto"},"tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0c9091ebd75b8c770169039a06b7f081939b87f99a680e70b5","object":"response","created_at":1761843718,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-mini","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0c9091ebd75b8c770169039a06b7f081939b87f99a680e70b5","object":"response","created_at":1761843718,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-mini","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","type":"reasoning","encrypted_content":"gAAAAABpA5oHfxppmLDktuWhr3oHJCbNjqjxJ0b13z0IfCwDZeMOhhO1IPpfxxFzdV-VYzhQunZ_yTOCappVChaMMcqXxDEi0PBgY6bgzff-D0uQMn8zwZ9MjnH5WXndf2bK-s3MSKIUiyi3T3lePqNtYgUYZPbpNnvYjiSlhdjUuoXrcI6__41YIE68jdYn5dbUp2qyjAcWylGSmZlWNxnYiHrXnvEQgVeFjUMVwbG0_Cl7btjafxmZoeTjSC7FowwBwmC24VTjcgqB3-bZpvjHOrvIivS7IFvA2vle60X12M0HQMgHpl3wVaYUCQ8SQ9HLjyOTetNCmzrFcq3S7G1bHaAhwbiM9WPvuDz4zTiL2-h7whrWydnnD0AmoPAtUkHVno_XePFL_2x7-ljDpM8QX0hR6BtMp3VHRcXHAImNwnuFJ4ivrBsIdxhYfNBaUEAdCJPzdGJf567PQDfXjE0MT2yODxkU6qkkSzfqzMrfwtSZmq_sQl7rkPX38QdnedK5U9IIFNa8Akc9ltRR_WEw-miMdfLYgNEAB9YJw6tG2uHSdVYx6SJuzrT6ZwERJ-2pdnD3H0pS5C6vSrhO_FiyeYdnP4-7G21uGPLBd65lYOG5ckHBYCOTgCSoS4udb6xGPeNh4AJEVp7h4U_kWq3WE2cfj-Zn5_5IGRpLuU2fkWw4q9stbyaTmjJUZcfv-CwAvhRww7HPSNyz7k_Ee-0cLv3SxBv_366eFSHb9LENqpWZikQuHl3-VF3gIcPVlsKHsctxGiAe_UmwJzFeDZY6rUPv6lIpSwfOJfpRf5XRjya0GTGCBiI=","summary":[]}}
+
+ event: response.reasoning_summary_part.added
+ data: {"type":"response.reasoning_summary_part.added","sequence_number":3,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"part":{"type":"summary_text","text":""}}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":4,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":"**Checking","obfuscation":"ZD5qQr"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":5,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" the","obfuscation":"UdDx5nQAVP45"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":6,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" weather","obfuscation":"KQnZy5Vc"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":7,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" in","obfuscation":"3aW6QjZymesN1"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":8,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" Florence","obfuscation":"uK2DNjX"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":9,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":"**\n\nThe","obfuscation":"8K2k0gvpc"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":10,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" user","obfuscation":"tzmx95KR8sC"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":11,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" wants","obfuscation":"ZHhQKoXueh"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":12,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" to","obfuscation":"SFCm5WizbKpU1"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":13,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" know","obfuscation":"O1KRvH3M9Oh"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":14,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" the","obfuscation":"qjHPP0sufxuP"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":15,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" weather","obfuscation":"2uCklVPv"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":16,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" in","obfuscation":"KEp2TpfCrMONL"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":17,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" Florence","obfuscation":"Cq7O3RK"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":18,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":",","obfuscation":"BS9oEz2cLKwuA2W"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":19,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" Italy","obfuscation":"nWeCzUC36T"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":20,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":".","obfuscation":"Ebs3L4rPWdbTUxi"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":21,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" I","obfuscation":"wJslgRTaDNZcLC"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":22,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" have","obfuscation":"OTo85cU3Xls"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":23,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" a","obfuscation":"r5EX1KM8gR6WYM"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":24,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" function","obfuscation":"5JjfFUn"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":25,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" available","obfuscation":"FzQgwx"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":26,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" for","obfuscation":"D7VGcsfBXSvK"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":27,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" this","obfuscation":"Te8DS1S87n9"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":28,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":",","obfuscation":"Ltfq3FqZdGZPBDm"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":29,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" specifically","obfuscation":"RRt"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":30,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" designed","obfuscation":"H2Oepbo"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":31,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" to","obfuscation":"YOEEdM5o4HMu6"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":32,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" take","obfuscation":"otwy4nQJ4SW"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":33,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" the","obfuscation":"QVohITAnifu9"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":34,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" location","obfuscation":"nCHirgu"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":35,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" as","obfuscation":"1oxHGAtqRypyR"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":36,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" a","obfuscation":"3uLeP2kJbW2yuN"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":37,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" string","obfuscation":"NkiYI4gal"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":38,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":".","obfuscation":"iPK84iI57rqNrlu"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":39,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" Since","obfuscation":"dtArqMpHn0"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":40,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" there","obfuscation":"q46iKUMq0o"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":41,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":"ās","obfuscation":"H5jyxCJYeV4pyc"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":42,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" only","obfuscation":"xWvgBOa9y29"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":43,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" one","obfuscation":"gZm20XZ0MnSV"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":44,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" tool","obfuscation":"cSaOumHhw8d"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":45,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" needed","obfuscation":"Rk5LmSZnz"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":46,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" here","obfuscation":"dLjFGxaGQy4"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":47,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":",","obfuscation":"ohGyw10ipm9AKAW"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":48,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" I","obfuscation":"eTqH2Mp1B7g9uz"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":49,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":"āll","obfuscation":"29MLpieYRKXgf"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":50,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" call","obfuscation":"APlYstxBHTs"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":51,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" the","obfuscation":"TcsBlCiNVprh"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":52,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" weather","obfuscation":"avvWR2K8"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":53,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" function","obfuscation":"O1zxplU"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":54,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" with","obfuscation":"5D7hNVM9ZJX"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":55,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" \"","obfuscation":"0ADmV6WCq7LJhy"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":56,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":"Flor","obfuscation":"Hft9t8FfJ2OT"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":57,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":"ence","obfuscation":"SxhbGyIH59Rj"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":58,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":",","obfuscation":"yrih8YHiYqhyJIM"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":59,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" Italy","obfuscation":"taxM0svrCN"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":60,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":"\"","obfuscation":"AXmtTJdHl0ct71U"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":61,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" as","obfuscation":"WMRLlJ2zfdWBZ"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":62,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" the","obfuscation":"Afw9DMHirE9s"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":63,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" location","obfuscation":"LaWrtlT"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":64,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":".","obfuscation":"sMtk17vbSNlu9B4"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":65,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" I","obfuscation":"zW2mIqooKFSvYD"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":66,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":"āll","obfuscation":"MrleqMeZG2uIW"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":67,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" utilize","obfuscation":"3UtSAyvp"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":68,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" the","obfuscation":"Id2PxWKevjQp"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":69,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" commentary","obfuscation":"C1n9m"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":70,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" channel","obfuscation":"JnqRB01s"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":71,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" for","obfuscation":"JZ4hLhjIedIi"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":72,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" this","obfuscation":"TA2UVWLPUt6"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":73,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" call","obfuscation":"jUb5GFeErrf"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":74,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" to","obfuscation":"TeODaVrEwaolG"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":75,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" ensure","obfuscation":"kWJCoasus"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":76,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" seamless","obfuscation":"oiDGzIT"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":77,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" execution","obfuscation":"CmnvwZ"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":78,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":".","obfuscation":"PvCPxbVr9AgEhtc"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":79,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" It","obfuscation":"RibP4SWMIr9Os"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":80,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":"ās","obfuscation":"xwkQTTZvDyliKz"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":81,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" straightforward","obfuscation":""}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":82,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":",","obfuscation":"yPuwIjzMtPo6qaa"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":83,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" and","obfuscation":"ro0f5gmNp8Wn"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":84,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" I","obfuscation":"seWzdUEryqBWoW"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":85,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":"ām","obfuscation":"pM59Mrz4qiMm29"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":86,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" ready","obfuscation":"4kuj1VyApb"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":87,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" to","obfuscation":"yfPG0IKDaV5N2"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":88,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" fetch","obfuscation":"5cah6iIXM9"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":89,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" the","obfuscation":"ioGKWJfA1kyc"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":90,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":" information","obfuscation":"4oaB"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":91,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"delta":"!","obfuscation":"z2u9DnIpuLMulCp"}
+
+ event: response.reasoning_summary_text.done
+ data: {"type":"response.reasoning_summary_text.done","sequence_number":92,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"text":"**Checking the weather in Florence**\n\nThe user wants to know the weather in Florence, Italy. I have a function available for this, specifically designed to take the location as a string. Since thereās only one tool needed here, Iāll call the weather function with \"Florence, Italy\" as the location. Iāll utilize the commentary channel for this call to ensure seamless execution. Itās straightforward, and Iām ready to fetch the information!"}
+
+ event: response.reasoning_summary_part.done
+ data: {"type":"response.reasoning_summary_part.done","sequence_number":93,"item_id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","output_index":0,"summary_index":0,"part":{"type":"summary_text","text":"**Checking the weather in Florence**\n\nThe user wants to know the weather in Florence, Italy. I have a function available for this, specifically designed to take the location as a string. Since thereās only one tool needed here, Iāll call the weather function with \"Florence, Italy\" as the location. Iāll utilize the commentary channel for this call to ensure seamless execution. Itās straightforward, and Iām ready to fetch the information!"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":94,"output_index":0,"item":{"id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","type":"reasoning","encrypted_content":"gAAAAABpA5oKJk2zG0lDqeI0Evg60Jdbqsockm-Jl0d20EuuYhKSrLthw6S2LqORlLNbSOtRN62ZQIGaL48JNu_xkyF2hnfugZTXA7mIUphauuphV5DSLLpWO60McWy7SaRkkAmt1BVk1aQM_1HFCXiNu8eJHHnC3c6y77FqCkaa4-YQupPehJW8ssfD4Dvwg2Bmmrcc15PDBDgJCLGEVBocxmTmjJ9AG5lpaHL3LW1G3jXEA2K1rHJzFbgjnfXv0Mi3_9Lynp0-BT-SAcGBrbilBCQojBgzQkpBLL7-k4_TGacZZ-2LsEn6u5qBoH3hE1FUu-rUEPBn2Yj8o3t_7Q16nbfSQspWvKWYjG0M_wrDpekEWblBejitBuqrpjAhBlTRG_scI_SSoIFwfD4YX01YW9k44AKg0nN9zS3_nKXVuSlOjUSewEJMwXsP5wfzSCT3RLv7wAcE2Y08sNHbckdSuERAtAalUHNCmBne3WV6AvUTBYEbQWwf9JKhEr_R8P-TzTp1bQonEAG5zmSDhIqS4APcAzbAEsIYA3k1rhvQXEfX2y_0dLgaxor0ww5y8FOemVyxt7CrEJ7Hggp34XPxwpjkLb2QZnFHBNJdNY_YN2pxgQ42hz3yD9GVSdMTqAVbi2bLc341Li7xgrjJPvRcUnWolxmVos_kqOB2avQ7trVPR3xZ3P8aj7hGuYqOd4aWbeNWKupjvY7rDSTi8Dq8k_k9rQ_srRKDRk6U1b6asLSZYCBXWLn0s_J_iD5-Gw6kaKZ6DdMtpn8YuQiM_n6UJDGD8Sh69Mqn9cBGigczYgYoZ8l2XSEqhXeJK8u4Xv6YgctE7-Z8i53o4iYmy3aaweJtbrWeZOODPZZrjSxLCx-NDCNOUZMATzXbg3HTbC4sbwDyc-xskMykOg3Da4bf6C7Vxd0aQQ4Vy9X6nqLaJc-lQyCRi5HpaVnj3cBn-4Vf1vw_hUW28BiK8r_P6-jCc5AF0zjxps-jC8ZJ8tYjke0sJXOMao7I9UKPvMhXWtvE1KgPulMEeNgXvd7mZT3qEUSp1YasJqZFVIpsbxubiiAjRtREpeFGADfggHjTU09xHRLg75si6jyMpFolFSCyHhRGTjbEI0oIyeqwDFXqdfX_Jhl69t7lXe2Keg7mfwx41EYV6_PCCKXOTSEi5MWJpsstpfAYCDQT6GOjrxK27lBNzGmRuny8PFlkrndbzy4on3yWGk-1vc7UZuJ5eibptpZwyU7SUt8H154TQOLtsaSfUooZoEOE73GDgdBuk_FCsi1ZP4KT30yv164Ln_HsyPHLYW0Qfg==","summary":[{"type":"summary_text","text":"**Checking the weather in Florence**\n\nThe user wants to know the weather in Florence, Italy. I have a function available for this, specifically designed to take the location as a string. Since thereās only one tool needed here, Iāll call the weather function with \"Florence, Italy\" as the location. Iāll utilize the commentary channel for this call to ensure seamless execution. Itās straightforward, and Iām ready to fetch the information!"}]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":95,"output_index":1,"item":{"id":"fc_0c9091ebd75b8c770169039a0ab6bc8193ba9f32d4efe182bc","type":"function_call","status":"in_progress","arguments":"","call_id":"call_2897d2a0YobhHQSGblq4C1iZ","name":"weather"}}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":96,"item_id":"fc_0c9091ebd75b8c770169039a0ab6bc8193ba9f32d4efe182bc","output_index":1,"delta":"{\"","obfuscation":"pDyKXP24KrqBcg"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":97,"item_id":"fc_0c9091ebd75b8c770169039a0ab6bc8193ba9f32d4efe182bc","output_index":1,"delta":"location","obfuscation":"d4lh3gRo"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":98,"item_id":"fc_0c9091ebd75b8c770169039a0ab6bc8193ba9f32d4efe182bc","output_index":1,"delta":"\":\"","obfuscation":"CY3YstcoSUdbE"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":99,"item_id":"fc_0c9091ebd75b8c770169039a0ab6bc8193ba9f32d4efe182bc","output_index":1,"delta":"Flor","obfuscation":"3fc8qTUcq8b6"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":100,"item_id":"fc_0c9091ebd75b8c770169039a0ab6bc8193ba9f32d4efe182bc","output_index":1,"delta":"ence","obfuscation":"BvgjOXHTIqjA"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":101,"item_id":"fc_0c9091ebd75b8c770169039a0ab6bc8193ba9f32d4efe182bc","output_index":1,"delta":",","obfuscation":"cOCgEX9nSt6XKoA"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":102,"item_id":"fc_0c9091ebd75b8c770169039a0ab6bc8193ba9f32d4efe182bc","output_index":1,"delta":" Italy","obfuscation":"0jUswSFIUV"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":103,"item_id":"fc_0c9091ebd75b8c770169039a0ab6bc8193ba9f32d4efe182bc","output_index":1,"delta":"\"}","obfuscation":"BruFF5x5i3wI7H"}
+
+ event: response.function_call_arguments.done
+ data: {"type":"response.function_call_arguments.done","sequence_number":104,"item_id":"fc_0c9091ebd75b8c770169039a0ab6bc8193ba9f32d4efe182bc","output_index":1,"arguments":"{\"location\":\"Florence, Italy\"}"}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":105,"output_index":1,"item":{"id":"fc_0c9091ebd75b8c770169039a0ab6bc8193ba9f32d4efe182bc","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence, Italy\"}","call_id":"call_2897d2a0YobhHQSGblq4C1iZ","name":"weather"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":106,"response":{"id":"resp_0c9091ebd75b8c770169039a06b7f081939b87f99a680e70b5","object":"response","created_at":1761843718,"status":"completed","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-mini","output":[{"id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","type":"reasoning","encrypted_content":"gAAAAABpA5oLoDdu1woYmtpDZQRsOWCRUusCH-qCyVJ9b3FmZBMnrySPvUB6PltEOiLG5lfwz7eHG0EX_4fMLSYMTGfzhNk1qVW2mj0N9NP-CYSOscKFGjqv8YwDR1qW3pQnhssfw7gOZql8puHJEoQ2roBJGIPibSLjQcUK8cUAb4w737IVqRfdCzALczFeFaNsBhOY4Cyb1dmq-zTb-tddKVeSz11qoMTU_PBg1wYyDJfrLql2RCFKCnpK0SxfZFwA4WijOwau3HeYqyQxYa8uL_iqQBP684hZOD60vwSj4eQy4dRxKEoFwu5giWCq2e6Y1fz8QKmHbVyNr2FGgDAxlhufXxC-BaP54wA4pKX6ee9UgPHkLalw78AITdu3zovYjzH3uVbGLJ3Y29icS2pCkku6sF61jeLM0OCncj9PcgdOuOHDqpVKjCU77b1JFUs7BqK3L-s3R9PCY8YtpzqbYbYnL6VbYbTgfw_zMCcYDllrZeEG8bN4oZ15pTLVmTO7Fzr9WZ4pGngT-DMx0AUkOL708kRUQP34nyh1xReKALUvk2OHkxUFvzh12oLCvSBJc6_KLFBTFGEi6nK2GnVsUbJXciWnPB0Ca2hnX48f46wXSX_7bqYCzvA7dohkUQ8-_5U2VzElZoDm34WhcqG3ITLoRTr2HftHvE1UAwa9HcQs3Hmm1hJtKRm0LM_9MlDOdzFR3V27oF2jp7YORZLYCqjrAgODeR6Jj45Bz7SuVY4m7QY6NoBiyEN9CDttDw7AoK9jvs4763lFAkVD5uEPdFCH0hI92YoDknwQcY97Tjt703qFO7hmE1RUp8CXqGLBrkfMDNyM8tpgLMXtuyDqjnBkTUKw7ZO0B86LCczzRoOIiOqDZpqPRk6CxaSYz4rpiIMn93OqPfHBVIxhhdoclVwHeNpPMj1CC2BVbEgm-YcDscW_ivZdSjFYdr83sWqR7aSN9O_GdBK4xcnX7P4xpM7I1E1WDwTxDMeB32goZBoC6-Pl457cKKM15rE5Vmwn-arXqsQGc5LeZunB0tt0wT73kjdr9YbKLpaFaBSjUH6KSvuajYge7I9RSi4haStGdA9hA78Q1oAU-cTpA7J81DhZveOnFTiIHK7xf1qI5kBkR0Wy_AqCtpj-tKtqH3_yACyAC6TnjSPy0EXmxYuWfNdjQUzfD3kEn2myMy-iYZyDU6riflxNw9WucDep_HGJ_YDlI8s7DCnoJAdKWpOSefzqvl_3AD6FINNO70eEc_EyYf7YPX_Q839bit6FU75DTkpXHv_drwtcAdPoSPb9rbMr-msB9w==","summary":[{"type":"summary_text","text":"**Checking the weather in Florence**\n\nThe user wants to know the weather in Florence, Italy. I have a function available for this, specifically designed to take the location as a string. Since thereās only one tool needed here, Iāll call the weather function with \"Florence, Italy\" as the location. Iāll utilize the commentary channel for this call to ensure seamless execution. Itās straightforward, and Iām ready to fetch the information!"}]},{"id":"fc_0c9091ebd75b8c770169039a0ab6bc8193ba9f32d4efe182bc","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence, Italy\"}","call_id":"call_2897d2a0YobhHQSGblq4C1iZ","name":"weather"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":63,"input_tokens_details":{"cached_tokens":0},"output_tokens":86,"output_tokens_details":{"reasoning_tokens":64},"total_tokens":149},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 196.11175ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2234
+ host: ""
+ body: '{"store":false,"include":["reasoning.encrypted_content"],"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence, Italy?","type":"input_text"}],"role":"user"},{"id":"rs_0c9091ebd75b8c770169039a07341c8193ae5619f70d498e71","summary":[{"text":"**Checking the weather in Florence**\n\nThe user wants to know the weather in Florence, Italy. I have a function available for this, specifically designed to take the location as a string. Since thereās only one tool needed here, Iāll call the weather function with \"Florence, Italy\" as the location. Iāll utilize the commentary channel for this call to ensure seamless execution. Itās straightforward, and Iām ready to fetch the information!","type":"summary_text"}],"encrypted_content":"gAAAAABpA5oHfxppmLDktuWhr3oHJCbNjqjxJ0b13z0IfCwDZeMOhhO1IPpfxxFzdV-VYzhQunZ_yTOCappVChaMMcqXxDEi0PBgY6bgzff-D0uQMn8zwZ9MjnH5WXndf2bK-s3MSKIUiyi3T3lePqNtYgUYZPbpNnvYjiSlhdjUuoXrcI6__41YIE68jdYn5dbUp2qyjAcWylGSmZlWNxnYiHrXnvEQgVeFjUMVwbG0_Cl7btjafxmZoeTjSC7FowwBwmC24VTjcgqB3-bZpvjHOrvIivS7IFvA2vle60X12M0HQMgHpl3wVaYUCQ8SQ9HLjyOTetNCmzrFcq3S7G1bHaAhwbiM9WPvuDz4zTiL2-h7whrWydnnD0AmoPAtUkHVno_XePFL_2x7-ljDpM8QX0hR6BtMp3VHRcXHAImNwnuFJ4ivrBsIdxhYfNBaUEAdCJPzdGJf567PQDfXjE0MT2yODxkU6qkkSzfqzMrfwtSZmq_sQl7rkPX38QdnedK5U9IIFNa8Akc9ltRR_WEw-miMdfLYgNEAB9YJw6tG2uHSdVYx6SJuzrT6ZwERJ-2pdnD3H0pS5C6vSrhO_FiyeYdnP4-7G21uGPLBd65lYOG5ckHBYCOTgCSoS4udb6xGPeNh4AJEVp7h4U_kWq3WE2cfj-Zn5_5IGRpLuU2fkWw4q9stbyaTmjJUZcfv-CwAvhRww7HPSNyz7k_Ee-0cLv3SxBv_366eFSHb9LENqpWZikQuHl3-VF3gIcPVlsKHsctxGiAe_UmwJzFeDZY6rUPv6lIpSwfOJfpRf5XRjya0GTGCBiI=","type":"reasoning"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_2897d2a0YobhHQSGblq4C1iZ","name":"weather","type":"function_call"},{"call_id":"call_2897d2a0YobhHQSGblq4C1iZ","output":"40 C","type":"function_call_output"}],"model":"gpt-5-mini","reasoning":{"effort":"high","summary":"auto"},"tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0c9091ebd75b8c770169039a0b5cc481938e22c048a363f0af","object":"response","created_at":1761843723,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-mini","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0c9091ebd75b8c770169039a0b5cc481938e22c048a363f0af","object":"response","created_at":1761843723,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-mini","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","type":"reasoning","encrypted_content":"gAAAAABpA5oMHsXNUGdxaafKmCihHCaLUrFR2s-Ct867NBUh-2EwCSxNPZsPPFdqSGo0mIAAI8J2ULZ2eaCeP1MMNfRhSvC_OIrILnw3cqLBW5w-YJij1rVmaoAZo87m_BXcDvFrT89Dx2X3kjvMVpCh9rZLk4XaNyHLVrPTPVXuUOQYFgW1oLvnp-rAH3FM8Y8YYq36wGPJWIuhQuVJImQyYFqn-Oy9_JlinjL-FTuK8tl2yPiHoDOOliL6lAJT8Tor8NsGkBAk0snFkrDIFtjreOy8MIY3YZA8JCqFzb_6l39BKokNEoa-U7wnHy92dlbs8VSmQmIo_GN_BXNUz3gNhthOT8_WdPtz49CWo8j2-rk-76XZcM19DK4fnH-tm-5O_TPvqK6BIloSKouvjPQ3M-3XRwiHPtROvcybVULbfHlEQujP_wVFT0l80V3GnsWLPJznKI1ZI56i9F54JrunH2Qcos9_DzSRJOLBOBO_RtWw9xLJVDvBAWloKkw0n1ernSio8zg6KPb37qsk0q6PODLsoZARzlAPEPoBR-YRg7jNohLsHA30FstEwv6fmR6jspQFHThoe0_-RYr_281Xu2tv6J1YD1ywg1D34bF76RFZ7XYtn-cZJ9CaGGN_pacnhFUW24Wz4YQvTDzdSu9_YpVgvfAWYT5pTEe0H0hk7n-R1xTiIwbgUN7KCCiTFP0cMAzuoNuMJ5Kv8zdT_jxvyQAlEoHn0zkv2nefV-mKc0JyOY2RtJlv4asFxTNRRWdZFDginOCPwoOBfF4Pb-1sWqwPwgZYzwbDzr-5W0aW2tycKo68xaA=","summary":[]}}
+
+ event: response.reasoning_summary_part.added
+ data: {"type":"response.reasoning_summary_part.added","sequence_number":3,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"part":{"type":"summary_text","text":""}}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":4,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":"**Reporting","obfuscation":"5gQos"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":5,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" weather","obfuscation":"UwpJaPuA"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":6,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" in","obfuscation":"yqbS7YremyW69"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":7,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" Florence","obfuscation":"09p5ylF"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":8,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":"**\n\nI","obfuscation":"1erPdWry9OU"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":9,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" received","obfuscation":"qWT2OUw"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":10,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" a","obfuscation":"G9vHw8GohXRwEL"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":11,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" response","obfuscation":"nbPaQQh"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":12,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" from","obfuscation":"bMi1JyxHCzl"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":13,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" the","obfuscation":"Ig8Zd7uv0LFj"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":14,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" weather","obfuscation":"myTAJV8S"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":15,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" tool","obfuscation":"iucdAHkrfts"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":16,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":":","obfuscation":"kXoDqAyXTUuPnzE"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":17,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" \"","obfuscation":"5eQf0bxhx5NLyy"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":18,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":"40","obfuscation":"SZ4BBgFkUhpJOL"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":19,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":"°C","obfuscation":"UHwVFRt6tPSL9G"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":20,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":",\"","obfuscation":"2p9tOp1xAQQjyI"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":21,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" which","obfuscation":"GomvtOQ4Gv"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":22,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" seems","obfuscation":"J9wuxMsTCv"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":23,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" to","obfuscation":"X2zmzbzM4oFda"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":24,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" be","obfuscation":"ROjQI6ZXY6Ubb"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":25,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" the","obfuscation":"nGYRWuCDJnct"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":26,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" current","obfuscation":"KPwSg9rV"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":27,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" temperature","obfuscation":"37LF"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":28,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":".","obfuscation":"KpXirMiFrHjRSR4"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":29,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" I","obfuscation":"ltWYJfcWvyGF10"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":30,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" need","obfuscation":"hwqBl2ll59o"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":31,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" to","obfuscation":"hBeGzZdt3KCC6"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":32,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" communicate","obfuscation":"lmHV"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":33,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" this","obfuscation":"hfYRpzjT3Cm"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":34,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" to","obfuscation":"DAWciMuJfMHUD"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":35,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" the","obfuscation":"NBFESvopGSzJ"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":36,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" user","obfuscation":"DyOnP2Ay1qi"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":37,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":".","obfuscation":"jGcGVed1ueHCrUf"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":38,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" I","obfuscation":"xrdQUQ3fkzbEVu"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":39,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" should","obfuscation":"VScWKYyzf"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":40,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" say","obfuscation":"kvSuIAu1ytyG"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":41,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" \"","obfuscation":"SKs3i3BE16BamR"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":42,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":"The","obfuscation":"IinY2VnfKokdp"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":43,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" current","obfuscation":"VSBMDVeo"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":44,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" temperature","obfuscation":"2GDr"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":45,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" in","obfuscation":"mJY4GlOIntEoL"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":46,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" Florence","obfuscation":"UFAPRWk"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":47,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" is","obfuscation":"Y4OnrlWdlBEtY"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":48,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" 40","obfuscation":"IS9pXmRzTxvcM"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":49,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":"°C","obfuscation":"zKVUPB1SlvItXg"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":50,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" (","obfuscation":"XoMglWuaflLGX9"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":51,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":"104","obfuscation":"rqTB5uyy3HgEC"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":52,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":"°F","obfuscation":"lXMfySda8WEpDc"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":53,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":").\"","obfuscation":"8F0gFcXYWL5T0"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":54,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" It","obfuscation":"7ZgOIw0oq922R"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":55,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":"ās","obfuscation":"zagMSMI8iZpLoS"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":56,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" definitely","obfuscation":"NSfq8"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":57,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" hot","obfuscation":"hrcK53KJShnX"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":58,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":",","obfuscation":"YD25fDahFL6LJ0D"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":59,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" so","obfuscation":"KBEYwFhRe0shR"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":60,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" I","obfuscation":"onaKnofE27wVAP"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":61,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":"āll","obfuscation":"6ZUdrW42KbUiA"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":62,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" recommend","obfuscation":"FTuouT"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":63,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" staying","obfuscation":"yOAGUiey"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":64,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" hydrated","obfuscation":"kSNmgSx"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":65,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" and","obfuscation":"XTi4eJ2Q0Lq8"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":66,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" finding","obfuscation":"sP768FSQ"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":67,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" shade","obfuscation":"VvenwZXf90"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":68,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":".","obfuscation":"rmEyh5b1Mcmj3cR"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":69,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" Since","obfuscation":"TyqlAAFS3f"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":70,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" the","obfuscation":"LlRdEhsRMHb3"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":71,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" tool","obfuscation":"f6p12JrND8R"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":72,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" only","obfuscation":"d1I2nSpmIBS"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":73,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" provided","obfuscation":"EQ9BLBa"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":74,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" one","obfuscation":"9ZxPVBexaHKa"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":75,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" value","obfuscation":"vhTvlR83p4"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":76,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" and","obfuscation":"xdmVZycS2Ylr"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":77,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" no","obfuscation":"y40O9OeuBhg7m"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":78,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" specifics","obfuscation":"sCr0So"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":79,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" on","obfuscation":"HdoCRImDBs2DS"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":80,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" conditions","obfuscation":"GbmmC"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":81,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":",","obfuscation":"OAlBtHulWPzEalx"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":82,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" I","obfuscation":"CtUT8i6m9hToSk"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":83,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" can","obfuscation":"BAOpECzQOaTO"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":84,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" offer","obfuscation":"O24rtxx9P2"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":85,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" to","obfuscation":"42xBSJNVXrE9h"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":86,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" give","obfuscation":"pV1icF1v8gj"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":87,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" forecasts","obfuscation":"VWmZOc"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":88,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" or","obfuscation":"Pi4IUyyxHMKBe"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":89,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" advice","obfuscation":"BXXJDeNx5"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":90,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" on","obfuscation":"f6LgRvEityZy4"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":91,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" humidity","obfuscation":"uUo2LQz"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":92,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" and","obfuscation":"cE1pU6IIXFq4"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":93,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" wind","obfuscation":"rRBZx4wWNso"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":94,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":",","obfuscation":"hUOsIhEP83QN3GK"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":95,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" along","obfuscation":"3wJMPpgOTE"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":96,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" with","obfuscation":"UIDt9oAjKRT"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":97,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" potential","obfuscation":"lzNnY9"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":98,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" local","obfuscation":"vdZi1cFeye"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":99,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" heat","obfuscation":"YWzkvP2kp3d"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":100,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":" warnings","obfuscation":"SUgDlZi"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":101,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"delta":".","obfuscation":"brFkCVHcYXqaROO"}
+
+ event: response.reasoning_summary_text.done
+ data: {"type":"response.reasoning_summary_text.done","sequence_number":102,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"text":"**Reporting weather in Florence**\n\nI received a response from the weather tool: \"40°C,\" which seems to be the current temperature. I need to communicate this to the user. I should say \"The current temperature in Florence is 40°C (104°F).\" Itās definitely hot, so Iāll recommend staying hydrated and finding shade. Since the tool only provided one value and no specifics on conditions, I can offer to give forecasts or advice on humidity and wind, along with potential local heat warnings."}
+
+ event: response.reasoning_summary_part.done
+ data: {"type":"response.reasoning_summary_part.done","sequence_number":103,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":0,"part":{"type":"summary_text","text":"**Reporting weather in Florence**\n\nI received a response from the weather tool: \"40°C,\" which seems to be the current temperature. I need to communicate this to the user. I should say \"The current temperature in Florence is 40°C (104°F).\" Itās definitely hot, so Iāll recommend staying hydrated and finding shade. Since the tool only provided one value and no specifics on conditions, I can offer to give forecasts or advice on humidity and wind, along with potential local heat warnings."}}
+
+ event: response.reasoning_summary_part.added
+ data: {"type":"response.reasoning_summary_part.added","sequence_number":104,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"part":{"type":"summary_text","text":""}}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":105,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":"**Craft","obfuscation":"v3lT9Lw58"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":106,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":"ing","obfuscation":"VUi4uixJQPPEm"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":107,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" a","obfuscation":"QLh9wwvR8zL4Db"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":108,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" weather","obfuscation":"6U3Ev4bl"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":109,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" response","obfuscation":"LiEP4YJ"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":110,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":"**\n\nI","obfuscation":"SFektGlMBvo"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":111,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":"āll","obfuscation":"Kv4hggvEocdUd"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":112,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" reply","obfuscation":"355XhtSQr0"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":113,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" with","obfuscation":"TvBDXURmpJG"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":114,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":":","obfuscation":"1GJoMPHVMSXePVB"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":115,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" \"","obfuscation":"n5VFC6vrJ5zYY7"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":116,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":"The","obfuscation":"MTC8iZh8LFkCI"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":117,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" current","obfuscation":"nfCQCUa3"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":118,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" temperature","obfuscation":"tTBT"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":119,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" in","obfuscation":"HjvSLho41uChe"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":120,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" Florence","obfuscation":"V0LmoS2"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":121,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" is","obfuscation":"lVSo2cezcapep"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":122,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" 40","obfuscation":"PYfEsYTuWRhsQ"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":123,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":"°C","obfuscation":"ImbxnkFzbKvhMV"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":124,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" (","obfuscation":"MjyYjtSMRwkO7B"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":125,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":"104","obfuscation":"CSrXbM3ZbBfog"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":126,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":"°F","obfuscation":"BpaV9oyZ4cxfxM"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":127,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":").","obfuscation":"CsCqaIPPphyvb6"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":128,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" I","obfuscation":"n5XCuVIZCLFGKK"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":129,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" don","obfuscation":"bUgCRoHDFNma"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":130,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":"āt","obfuscation":"1Oo9jQ1Lviz8yz"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":131,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" have","obfuscation":"Ia0gc5AYZUT"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":132,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" additional","obfuscation":"HuKIv"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":133,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" details","obfuscation":"rf57xXQs"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":134,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" like","obfuscation":"zoRtsGNCpdc"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":135,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" precipitation","obfuscation":"Qp"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":136,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":",","obfuscation":"YTuAfVimiDFoxFg"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":137,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" clouds","obfuscation":"yXUF41WUX"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":138,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":",","obfuscation":"XDmoR1WMpYDYCS6"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":139,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" or","obfuscation":"ARcgSEwQ1prmb"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":140,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" wind","obfuscation":"jCO0N6skNbE"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":141,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":".\"","obfuscation":"7ZNZvo70NJOW2s"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":142,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" It's","obfuscation":"znHeawO0fFJ"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":143,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" definitely","obfuscation":"BQ9TI"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":144,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" very","obfuscation":"jrReafNEgKG"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":145,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" hot","obfuscation":"ccDf9M1dwYcV"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":146,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":",","obfuscation":"tKTRhKI4f1NUgbS"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":147,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" so","obfuscation":"5BYkzw7QzTOuN"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":148,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" I","obfuscation":"7P5HGFoZK2LdAd"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":149,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" should","obfuscation":"sf96y5onP"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":150,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" advise","obfuscation":"pXuBeVaJm"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":151,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" staying","obfuscation":"2mLddFly"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":152,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" hydrated","obfuscation":"vHWJPko"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":153,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":",","obfuscation":"sA6etch6WftywUl"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":154,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" seeking","obfuscation":"2UweHpo9"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":155,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" shade","obfuscation":"B9w6TYk0Ke"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":156,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":",","obfuscation":"lDuxQqlRNyqeHqv"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":157,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" and","obfuscation":"ObORsgjVWUYb"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":158,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" avoiding","obfuscation":"RTTO4qr"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":159,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" strenuous","obfuscation":"AckJpN"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":160,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" outdoor","obfuscation":"LP3Qkxzy"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":161,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" activities","obfuscation":"mvveT"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":162,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" while","obfuscation":"Fa9ETGvRvN"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":163,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" wearing","obfuscation":"DK4l1ukE"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":164,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" light","obfuscation":"744PCnTN12"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":165,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" clothing","obfuscation":"9P9Fqcf"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":166,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" and","obfuscation":"NvZk96NvOisD"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":167,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" sunscreen","obfuscation":"aTJmiI"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":168,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":".","obfuscation":"MwRbmskoZqnPdsi"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":169,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" I","obfuscation":"UqfCe1lmvQkF0a"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":170,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" can","obfuscation":"ghkSKMGvLYKs"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":171,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" also","obfuscation":"ESGzyGD7Eqy"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":172,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" ask","obfuscation":"5DJZT0xXIBZo"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":173,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":",","obfuscation":"5h5B8LYCBKJcBwc"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":174,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" \"","obfuscation":"yyTfa1pyRmPSYx"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":175,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":"Would","obfuscation":"EQGJdKCv9Zk"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":176,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" you","obfuscation":"tM8jm0vPQMLJ"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":177,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" like","obfuscation":"l8kNxSfLCWu"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":178,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" a","obfuscation":"Wgoej4knJGyWAX"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":179,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" forecast","obfuscation":"YdSnH4F"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":180,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" for","obfuscation":"0PpeJ6cZyjix"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":181,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" the","obfuscation":"m1mN3O1VagcY"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":182,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" next","obfuscation":"hUL10Fx5BDJ"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":183,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" few","obfuscation":"6k2PWl0vsDUs"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":184,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" days","obfuscation":"fhnfdfopMr6"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":185,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":"?\"","obfuscation":"d0lRQhHFO43v6n"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":186,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" I","obfuscation":"m3iOXLEUzo90wA"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":187,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" want","obfuscation":"WD68YwKNyEx"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":188,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" to","obfuscation":"6ioZS6nWR7j1R"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":189,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" keep","obfuscation":"FCZE1feVQsL"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":190,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" this","obfuscation":"e72IQMlMM7H"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":191,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" concise","obfuscation":"trTiq3Ro"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":192,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" and","obfuscation":"FlaC5lwefou7"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":193,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" informative","obfuscation":"tRl2"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":194,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":",","obfuscation":"LVAuv792sDnEG9v"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":195,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" considering","obfuscation":"96AV"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":196,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" the","obfuscation":"83bHZCQkeWKJ"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":197,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" user","obfuscation":"8E3r91DsgX9"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":198,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" just","obfuscation":"GNTPSKBnBms"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":199,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" wanted","obfuscation":"doJgdTybb"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":200,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" the","obfuscation":"X4VgDMNE88cZ"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":201,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" current","obfuscation":"bXJjxZcU"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":202,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":" weather","obfuscation":"RdVQ78IM"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":203,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"delta":".","obfuscation":"HqFL1VaceRoDB2h"}
+
+ event: response.reasoning_summary_text.done
+ data: {"type":"response.reasoning_summary_text.done","sequence_number":204,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"text":"**Crafting a weather response**\n\nIāll reply with: \"The current temperature in Florence is 40°C (104°F). I donāt have additional details like precipitation, clouds, or wind.\" It's definitely very hot, so I should advise staying hydrated, seeking shade, and avoiding strenuous outdoor activities while wearing light clothing and sunscreen. I can also ask, \"Would you like a forecast for the next few days?\" I want to keep this concise and informative, considering the user just wanted the current weather."}
+
+ event: response.reasoning_summary_part.done
+ data: {"type":"response.reasoning_summary_part.done","sequence_number":205,"item_id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","output_index":0,"summary_index":1,"part":{"type":"summary_text","text":"**Crafting a weather response**\n\nIāll reply with: \"The current temperature in Florence is 40°C (104°F). I donāt have additional details like precipitation, clouds, or wind.\" It's definitely very hot, so I should advise staying hydrated, seeking shade, and avoiding strenuous outdoor activities while wearing light clothing and sunscreen. I can also ask, \"Would you like a forecast for the next few days?\" I want to keep this concise and informative, considering the user just wanted the current weather."}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":206,"output_index":0,"item":{"id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","type":"reasoning","encrypted_content":"gAAAAABpA5oXkQkuZ7auEqNLWo98OBrRqShGlh1yVrv5vq_wbv5AbBwYKDsTICx2fHGZkbe05e2qcEUyQoaYCndRanglXc6qth-tpQdnFWq_DNbIx8RHek4qtLk8QmayDxrQCK_DQlt4-hEtxFA9SuKCacwVxL3hHvW_48umG7zVD3vT3j7EXFwtQzpzRkPAnpGnJ7axx7SXi2hHzbUo6RZ_gPJQPrAhmrA9IOiqqTj9DeAT-nNu0gr-xAt6X7l6q0dD--ndngnf3eXPNaH8J3NrSpg9NEmQo-zvpDTTPUDWjkqs8ggnbXcqrv_EVl6dGIfNKapwsmBPeASD9MUmUnu2DhH3xW9HB0B64lm2rYgECwqel2zgzY64KkpaeX6tVpPHGW8Bzd8ftfco9kiJzDYPqrLrrbh0E3Xf0reF-IiWTGjE5u8jmoxweCACuKKNGo4vvCZV5Il3W3217H8MmpBFIoBax_Nu9sHcKJd5VA-7xR8xFO3_UGkk3RGbfwBmw_X4yt6rIx-z2_kuC6BhURq_wmf57KkFhXjDkLp9XFDqm6QXOGjIvRf61Y7OVHvx9FBd6SLjj_0WcmAfSLG8vtsVGJ_aF7sZljT-dtQNvZTJCEOZ-O3dbH3SlJWC4kTdNRPVq6_HWYsZng6DIjWlXH6nCX0qB9QsffZoJ4Ji0LXZ6XKTgZOp0kpGhaYYRkFPiumKjJgHZtY-8_OW-4ETpUu-UGvwYysZFd4grTbQ02x459JExPae6FMo6uTfDQ_-jHi14bq99D7Vmo7w_4mItfjAgd4GONo-0YKkiFYb6SSEqceCa5tJbevqs5mj-blRMjzWV1CT7xCAl3KkYA82E_oPtzVjzhp4gji7nCAL0hK69CmUfwt4iWyqecvtSZMHr0dcupyLjyHFlTB6LSViKz7bMgqt6Vo9sRXMhMsqS_7SD4fUtjrEQ5tXwTybPxY9ROesMdgUkMPjp_l3eLg--BIRlvsVDA1dW8N88JxmxjNvONoLvZwTEu-hqbMqIRbqW-kj7iHo0dnatUCUC_dAysiUTZsvpKvUj4b6du0LUTzTEWmwEXhBJshJGMpca4BzCXHSLRQoPXB3tDa31WL49kOLUjhi7dOJP45tLMJz2K9gA2TxXRpKeeOVJWv_ntbZ5DK1kwzMwoB-DwusFFY81ffrXti2jIO-7XRIJoH17NX5kHVqxjYHeq-YBFkalQ30odwW_ekv0toGY93rauQTe699tHVBgQ0L-7da45ZbKmqzKjLq_P3n4vUwXacqqWdxXh_1m9ZfGVxl1hZGDj0grWlDQ9QQ4RzXfTNdc-GQdFkFKAeJxKHJ4NcD3Ma_IMkCKzgGXfXGpF1RHAu6887BqasS6Cx0PYMs4F_5DpQdr5GddW2Y-tFvPtmBSkZO8ZFpdQEo1TcCltQmKYlsj2Ad4TZTca9lGrpy1yQElCrnZgqw6CihNnioRRNHoAkk2gcbGawbzpllBvG6huQPTq5zSwjypJk6Ee-qo5Nc78UuWBD0fV1wnUwDN2xoi7PC4PAuAE83QusuxhzepmdjvJNcNUS6lXUdV4sft11KzSOhYNRxaUm5UswwRWl8cf9vc-LbKuPCTkHwCWlyC5A_SXogsg6Yop8Ikd7JYvKFE36z-8cAN41In4xU1bpx-E4XmHbennu6L2pWA-kQGiT4cd01QY-lbrfgCd_ps-rjrcPUmtrJ71qgeIQsWi0wRNt2nQdx7nAgapCZHJSzGFhXX6vcVx8xFaL8VNtR2oPLbYr1kAarRz8IfSzMbPjlbMUcAJdWPXlw-3pG0afg9iZKrBps39N3lacOdIqlBqg-1ho1F-T28wH7RwxYpuVjlGeDM7ntKm_-7geMMnmjExDv5sn84RAWDx0A23Km29pO6bx8SZKaDCXitKW5yDtJ7qPAS5NzZ_iI2qEWctTLOpDnRvBufLDyc9eKSmrXEWMK_JwE0Ccy_C306BwI3HllnSOPjkFDMfJAf6gL4lXKOfDy5ef32Zp8z7RN5vtVFh0Ti_SixTq7Ku2ceuZz41Yu0gFQA_beOhQnR0jxlgMqHI0dm27JnraNuebupWsEN6rQMJyNuIdsPByT29n2_lIeYpqzqIZOc5n9amzG6ZSp9Gy5W76V2fzF-k_UoB62XquNowmWkkhhjCC-9FEdpR2BFNK4mETKW4N7fmO2uybBdWXl_l4RYvMespmM6k0Qq4twlMZujs9LZM4FTUqavh1XiZ2sMSdL32LvxJKcouj_sngxStBM2V79K5hcm63nPEXuwyMxiPVb52Nk4pPHp7mw3_GcdLoLDp-bYpy5mesGBNYb0ri0sbhgyZ8lDeR7Z6aAZB3Ha-JQG8s-ZDSrFon-4RqZeJaZw1L9nB0ryF6NMDJhQu1Ur531__g2rf71-lHXMBQaZLmoPyzCPZ1Pi9Ys2-YLIizsGhm40HDWnLPDmiXoSrGRRx8IxHYMtEI-qeH8pXR8lB07-aW4c7GXYYJ4mYT5P8LtxZn210iYdiC8rysqQ5BzwMW5IduDm_cVgknIjd9Ag1KiJT1Z-McJeMq5aaeO-EVINXzOk7Azi4w0eD33Njef7CAzgt5JgXl1nXnkIcZNeu4kR4VuS2HvZV47kaMhBnGaZnq_o8Yg2J3zmzKAcBg4aueX12A1Htfd4DhGjBv9tNAKPGMsuhjEGH6-ySEa59Ev87QPnB3UrdunIBvdCQyblNEJjS5ua9ouWTuxDjmNc-EhFHvR2TbTrSkAKbhDn05AbQnh_Pl8xRwPSqHHtV6Rm3reOD5wnfSqxVSxqehcR5o2rxOAmmbFlOFhTh9MnfqK6asXoLmyHTTDeKu0r4Mvj8KJupG0qR3mI4zX1HVyPZhj4ZerV5w9rEt0jMqYjcIoqtesm4EWj_WN2N_jy7VN9hWmNvPBNjKc9Pc1mEA8MH46OR38OEhp_IsGBtuKyEUbomve6TazhoEoXTWbVV_hPLqZQxC_BMTsKp8g5b3JStsRPPJQbsasYR2Nwn7LaMNEkhCtdoM6VlK7Tg91oZ1RlQPMvCz7cc9rdW1nrX_OlhBltl6Te-2QeC-5clUdNWdV1GCQkcBP3VQdcv59bYZmDk-O1Mk_HSkh_7H3jzeYiqP9xOLDv7q7NJy2wzO_UQvinDPDGPL3zK-u8ZI1kYtXx3ui0YbfxgFjwqzdYPvvST0u_HVThkTzCtfy0nfyQa37jYNSQlb0kgiA","summary":[{"type":"summary_text","text":"**Reporting weather in Florence**\n\nI received a response from the weather tool: \"40°C,\" which seems to be the current temperature. I need to communicate this to the user. I should say \"The current temperature in Florence is 40°C (104°F).\" Itās definitely hot, so Iāll recommend staying hydrated and finding shade. Since the tool only provided one value and no specifics on conditions, I can offer to give forecasts or advice on humidity and wind, along with potential local heat warnings."},{"type":"summary_text","text":"**Crafting a weather response**\n\nIāll reply with: \"The current temperature in Florence is 40°C (104°F). I donāt have additional details like precipitation, clouds, or wind.\" It's definitely very hot, so I should advise staying hydrated, seeking shade, and avoiding strenuous outdoor activities while wearing light clothing and sunscreen. I can also ask, \"Would you like a forecast for the next few days?\" I want to keep this concise and informative, considering the user just wanted the current weather."}]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":207,"output_index":1,"item":{"id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":208,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":209,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":"Right","logprobs":[],"obfuscation":"aLFURSQBQoA"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":210,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" now","logprobs":[],"obfuscation":"8UdNu8jwxPBu"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":211,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"PFmpW849yr7f"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":212,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" temperature","logprobs":[],"obfuscation":"cxGN"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":213,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"LbU13kYMYAPAb"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":214,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" Florence","logprobs":[],"obfuscation":"MkKwSOa"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":215,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"X69KGSNSpsGPh"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":216,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"WZHop2DTTosRHJc"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":217,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":"40","logprobs":[],"obfuscation":"sz3USSfU8CHYeI"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":218,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":"°C","logprobs":[],"obfuscation":"tEVfAM8ihNQuqK"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":219,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" (","logprobs":[],"obfuscation":"RNBdTgDvgMDhFh"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":220,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":"104","logprobs":[],"obfuscation":"fg94rneDTgriQ"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":221,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":"°F","logprobs":[],"obfuscation":"L6hH4m8f3GIurY"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":222,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":").\n\n","logprobs":[],"obfuscation":"ks0mFa0wJ8K3"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":223,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":"I","logprobs":[],"obfuscation":"C1wCdHJpOs5ra7x"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":224,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" only","logprobs":[],"obfuscation":"4mhhnrIcPdb"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":225,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" have","logprobs":[],"obfuscation":"IJRp3nAqliu"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":226,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"Kij8sQpeofgR"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":227,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" temperature","logprobs":[],"obfuscation":"yUKi"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":228,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" value","logprobs":[],"obfuscation":"9XaN3AqsX2"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":229,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" available","logprobs":[],"obfuscation":"LRTTRW"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":230,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":".","logprobs":[],"obfuscation":"oIhCcpvQqWTRnv7"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":231,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" That","logprobs":[],"obfuscation":"2nlBrGFc67I"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":232,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":"ās","logprobs":[],"obfuscation":"5oGOY5U1DBHC22"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":233,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" quite","logprobs":[],"obfuscation":"I8o9iJb3dw"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":234,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" hot","logprobs":[],"obfuscation":"s65VovZr4V4E"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":235,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" ā","logprobs":[],"obfuscation":"8U47s6dvqQY9H7"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":236,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" stay","logprobs":[],"obfuscation":"QF2NKR8kWxv"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":237,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" hydrated","logprobs":[],"obfuscation":"U6QQB6P"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":238,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":",","logprobs":[],"obfuscation":"BF4N1MkU7B7urPe"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":239,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" avoid","logprobs":[],"obfuscation":"VQGMPbg6Ni"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":240,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" prolonged","logprobs":[],"obfuscation":"RylbZY"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":241,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" sun","logprobs":[],"obfuscation":"0caBD4BQLwEW"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":242,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" exposure","logprobs":[],"obfuscation":"ZTuqeHr"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":243,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":",","logprobs":[],"obfuscation":"3Ev5k00wMW98urz"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":244,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" and","logprobs":[],"obfuscation":"x9OOAGYKcd58"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":245,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" seek","logprobs":[],"obfuscation":"yByqabxLVlm"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":246,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" shade","logprobs":[],"obfuscation":"ARNUENJt7t"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":247,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"vBmTlSeMJFtJ0"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":248,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" air","logprobs":[],"obfuscation":"8RzPEZPyhguI"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":249,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" conditioning","logprobs":[],"obfuscation":"GGx"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":250,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":".","logprobs":[],"obfuscation":"jYU088Q4Ri0TNel"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":251,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" Want","logprobs":[],"obfuscation":"4gces1yiiju"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":252,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" a","logprobs":[],"obfuscation":"mCjbR8qXeiUkBE"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":253,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" full","logprobs":[],"obfuscation":"8Keb8Z9EJxr"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":254,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" forecast","logprobs":[],"obfuscation":"5f5cR9k"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":255,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" (","logprobs":[],"obfuscation":"mxdCouBeT1hop4"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":256,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":"humidity","logprobs":[],"obfuscation":"ms1YVWaq"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":257,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":",","logprobs":[],"obfuscation":"51yZ7Slq6xVqQWx"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":258,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" wind","logprobs":[],"obfuscation":"9qKJD5rLY3S"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":259,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":",","logprobs":[],"obfuscation":"EqOs1HzNB4dd5qO"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":260,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" chance","logprobs":[],"obfuscation":"bHqovGVdT"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":261,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"Fq543J95A411o"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":262,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" rain","logprobs":[],"obfuscation":"XXGPVX0c4I8"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":263,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":")","logprobs":[],"obfuscation":"KUWxa2EqtpfY43x"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":264,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"wFtesRfHUwi1y"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":265,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" hourly","logprobs":[],"obfuscation":"g882SnQ2a"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":266,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":" temperatures","logprobs":[],"obfuscation":"DNF"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":267,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"delta":"?","logprobs":[],"obfuscation":"4JRjIkgmBnsSaXr"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":268,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"text":"Right now the temperature in Florence is 40°C (104°F).\n\nI only have the temperature value available. Thatās quite hot ā stay hydrated, avoid prolonged sun exposure, and seek shade or air conditioning. Want a full forecast (humidity, wind, chance of rain) or hourly temperatures?","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":269,"item_id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"Right now the temperature in Florence is 40°C (104°F).\n\nI only have the temperature value available. Thatās quite hot ā stay hydrated, avoid prolonged sun exposure, and seek shade or air conditioning. Want a full forecast (humidity, wind, chance of rain) or hourly temperatures?"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":270,"output_index":1,"item":{"id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"Right now the temperature in Florence is 40°C (104°F).\n\nI only have the temperature value available. Thatās quite hot ā stay hydrated, avoid prolonged sun exposure, and seek shade or air conditioning. Want a full forecast (humidity, wind, chance of rain) or hourly temperatures?"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":271,"response":{"id":"resp_0c9091ebd75b8c770169039a0b5cc481938e22c048a363f0af","object":"response","created_at":1761843723,"status":"completed","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-mini","output":[{"id":"rs_0c9091ebd75b8c770169039a0c6f488193a2546be206b48e07","type":"reasoning","encrypted_content":"gAAAAABpA5oY2GKSuuE2Ehkcr_wouVRq1-In-xjMSAH0EYlmgoIkUhe0DeqBivnc9z5Xw1l6Sy3ns-X1Mg1WOwWSWCyoKRww-0Hi2EAenBAWUK_3pWZK6e9AyVspiotxZRvSRJx46fhM5u-4iErcTPC8lcFtuzo1Zv97bCrjnRVHkWcDJx0uKtXynlEDFkUh45A_aAwDYbaJXkVvHnCPU0DmwynCbns-uhZnsc6wJIUJEvUqVZH9CfBVkbqO7tzB5M5AaHfMdkRGBzDZWc7Dxn4vsVh6Xxx--LDjSqLItm8sNlwxvN15jBa_wE2M7he6jHyyR1bMxMrq3vDreMbz7WOsT36fqHNRSSDGNj_Zm-iCrUrikWCQznSHKsxCLNIN-rWUPC4lWB8ovVAblFBvxFjUcY477KoFfBTVWPLVbIWZTaJmo0GXaCRriEhciQal_UljltqgWpGjWO-9dk5WwmP_xVh-SJGg6m6-pa63S0dZ3Q7AoaaPByFDMOLrHE2DMfRPxmC_DUeMmJk89evSmUS5NXB8QTBW6qJj0pbiAsCZO7eAL7K77ky6aQgL4RqR4LYd3KQf5LFkJrSUp6T8Jluw4JjeFy6x65-4BF97SazKp7G6eMxlYlYpIiiE0WuuUcY8GrMDIfRy1yQihcmhrrTCD5HzyiThQHY-eSwIle_LENlZxPH-mm2TUJ6vpK8dCNoK7559m6aCVyXeRBWIohcdLxtJvw4ikTSRbIIU0ngJBSfWuQ0LfzNSMXVjmTlHy2CxaeYWT0vm6cGDl6PIQkm1UoVv-8RSCR6A_d1lf3QL-mHopumP0ZBR-8_LDh9LrxTs63Tujf4gduGQ4wQuC2-8N30TijLnn1UXGk4b5onEMZZJm8TZQInNL9rjnv4tkaOjibjxKmoqU0fkZPRG-cKs0cdLkZob4nEXrEIW2lXicANMxcQBOGayDM1N6IJtxg6EtpX5bjwIrOZNIrUOYb0bJvVN_o_0gG30J0O9UFXr_CNGjpCG3dzi0Yz5omsiFUesPVZNJ0hTq-MjrDT-t0xuwOeWo1pRBluKaRyW0DDVIdZfc2SXKUaVT7tXCUDWFoMFEmQ8Ss8zzEgEcLXygZBDIyjBl-YctktqMbxN8XAXWPowib-EsABG54XYvg1KYAWUHkEIHf2Xp0muKpmC6E87AdZZi4tEbeYc9VBxYsPSMFfnAIXDa2ZqhU3r243JYZrwXCF2Nhxo8whAPbqqbxysH-qIPGf_1mYJnZmPdvnq3_eb9hyWl1qCKFgelr1HrImDj27X5-YCKWJyb5aUfl3juZI7yH32XSg4qiaZ_1-JjMnqPYnvk9hU3Vp2s-6phnCo6Sfy9krfG4ZvvPAtsKCJ2jUiuRegOFOxe40pv5j6Bt0CyGrZ3SrBzFe745t2wrgFjw8q7nPXCA98X3F6EXMmRRE0wiKvzB7YjYundKmdcVT3FlTnUx-acku1asrn1R5MvKllAhjHTwGQZ9R33twXcx-BE667Vn9338LZhFDjCXQdVa8MK0nqoG-gWBD3kkdZH6G0wyMqU-vwXHBIG7EkRyct0VOZqd2b10tnBpHZrn78GUPifV2CYtMLmwCNi-7v3XlaFj2rjbO7l5x1sYKqeDhW8soEUsASUPoAr829d9CbHOMGPxawSmX5cqdYPIpx8-jxs5FevgerIosCcdp4NSA7Z2DLlyP2Xs6NqjmbSrzrzNOhE-OJlfXKYpQEnIyIeFsvBM4mHyBs78Vn8zfIR49leAuthwCoFTDlc4dnGOeIQQjTtYTUcclfjMUiLZhzUhbhDcJmtpf3IUueDHdNNMq6vzVcsw2vWuf2zy4K1HwLpX_OUUenuuKCv9NHTKtxeA9MlwyTdXxAhRu1deKUSHzJ6ERpJGBoBYd93jW0_CEQLRlv_JKLJk0Z9_6VJUcHrF0G4hm-E_SPrZiGfsh583FQSLhixDPagta56qBVPUGjZCLg8CLearF5CdIlf8nU2cY_Ynf9O1fCinL_VXoUSyU5bmdjBBUNitHVTfQVd58BFhwKsbuxqmOfrAVlU83pnzw3LcW59UTgEUmqp2FsVLK-GfaYo8drLIJnLB1kLr4uvffx_FGwvOl4uMKFZvNNVsRvl_bC1HrmPn0tfkzpXH3kPccA4UcU13X9sfOmlBO8wtK0nw-Me-1acf4D6wCV1mn63waiihF8cS8c8P0zGjDK4Nym1zPE1sJrE3j2w8ZbvpkvUuKaq_w0Ekte7lacbQbJCmJ8EexHziC4pqgxNOwCMpI2C6NhPZDQdLaD8aYuMK__eDaFLzjrDmHlETrjjjOrEGnGi2EB79ok3Ai15H6_b4vrraFxKzfEu4_z-HkitdHIv3hH6798TicCAcEXmUkI86Go52gdZ6BW27KMrt32hTB2jXVF7pE78TawMpa4cG26e7zk2VOY-tQvOqvIlNABxlTgjAt4vYVDJ1RGrzZNtUDIBVa7KLKVzm-k5N-sk7sWBF_hrzCbFfob2zkuHP531m6gmYdrVdx9AvXMIPAW43A1xvSkJWRDKi8dRCVoCK4bKThBeSpsrPakuNzlsIOPrEQvEsCvJ2f1-UqkfScHFvU75KpmK-Lkk-_qlfHpVyke4JlE6rWec1nlkQwpLuikP1XcVDU-McQhUUNwqNuCNGZWKM_ldriLr_4ulU6Zs4yK9aYEVmu8ki8-bYurzCF_7gIhkWfWl9172aFxW8unckYkFTGvmk1B8mqBlFacMnf69R5GP9t87JXkzt4oUIcpxlhMSecwiLNt_3DtWeOaH7CWIvmVJMZpiv-MOaP2cqPe9-INwO9aDlzKo2LsRC0lRES9IWWqfxTpUfkaQT60ZH0W_9vzefR20cVSiNzrYytzOoaQseoGTbA7AX-W1CSNVhJV2-uK8a6IVgPyY-h4Ywt1mMF2qH0b8FmcP7K5RFa5LkjimQsL_Oi9cpGvwR5rHpgMRBjBDxtDlpZQ4ZeU54shVNc4nrxlcDkPXQK9cXqs90dBYniBZoWIx55k4fI98DgQvSUcChiNJsLsBItviT04AzyJSbb7HWk20A2kGxKPKzPNfhfpQ0DfvcwBeL3Uq3aPAhWuEzJyNR8JUTZlL8W_Y7iUdvIVRVxpzNIjOX2X-TIgQnwzQAV7FVGe58KPVLJ8WS8TH36Jf-0B1tRhH1Fz-9p1oCkhYJ4wZ31IFX29IqTN0hbtkY4aEYdqnJVogSET","summary":[{"type":"summary_text","text":"**Reporting weather in Florence**\n\nI received a response from the weather tool: \"40°C,\" which seems to be the current temperature. I need to communicate this to the user. I should say \"The current temperature in Florence is 40°C (104°F).\" Itās definitely hot, so Iāll recommend staying hydrated and finding shade. Since the tool only provided one value and no specifics on conditions, I can offer to give forecasts or advice on humidity and wind, along with potential local heat warnings."},{"type":"summary_text","text":"**Crafting a weather response**\n\nIāll reply with: \"The current temperature in Florence is 40°C (104°F). I donāt have additional details like precipitation, clouds, or wind.\" It's definitely very hot, so I should advise staying hydrated, seeking shade, and avoiding strenuous outdoor activities while wearing light clothing and sunscreen. I can also ask, \"Would you like a forecast for the next few days?\" I want to keep this concise and informative, considering the user just wanted the current weather."}]},{"id":"msg_0c9091ebd75b8c770169039a1760108193adffeb7c0dad2604","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"Right now the temperature in Florence is 40°C (104°F).\n\nI only have the temperature value available. Thatās quite hot ā stay hydrated, avoid prolonged sun exposure, and seek shade or air conditioning. Want a full forecast (humidity, wind, chance of rain) or hourly temperatures?"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":99,"input_tokens_details":{"cached_tokens":0},"output_tokens":449,"output_tokens_details":{"reasoning_tokens":384},"total_tokens":548},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 182.435583ms
diff --git a/internal/fantasy/providertests/testdata/TestAzureResponsesWithSummaryThinking/azure-gpt-5-mini/thinking.yaml b/internal/fantasy/providertests/testdata/TestAzureResponsesWithSummaryThinking/azure-gpt-5-mini/thinking.yaml
new file mode 100644
index 000000000..f1249cac3
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureResponsesWithSummaryThinking/azure-gpt-5-mini/thinking.yaml
@@ -0,0 +1,245 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 556
+ host: ""
+ body: '{"store":false,"include":["reasoning.encrypted_content"],"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence, Italy?","type":"input_text"}],"role":"user"}],"model":"gpt-5-mini","reasoning":{"effort":"high","summary":"auto"},"tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 3590
+ body: |-
+ {
+ "id": "resp_08e75323d01317c301690399f6df988190bbb2d99c071619c6",
+ "object": "response",
+ "created_at": 1761843702,
+ "status": "completed",
+ "background": false,
+ "content_filters": null,
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": null,
+ "max_tool_calls": null,
+ "model": "gpt-5-mini",
+ "output": [
+ {
+ "id": "rs_08e75323d01317c301690399f759088190a37f017516202cb2",
+ "type": "reasoning",
+ "encrypted_content": "gAAAAABpA5n8UjdGuSzFx6uvW1lDRxxYfY3gisRCV-3fmThjXt28KBNtZygO2FLKsTDYK4GGvbbqBGkaDynHzJFsQBMjvIyjkiLCdu8peexsbHa9xfp_cWzTgMxBsqQK2CDGxcXqokVV1V4u71ZWHvcV7RzevmhbxOn48CoA7FjOZBvyk2C9uCUh2NJs-GQeWP1zXFjDTcJS-_jZOUNxAw4COewYXTv0FHblhMbM9B61tnoflu6S4Xm_7qrWAuBtP9KSqEJQNCRCkRUtVfVThnG7u33pTQJGnd1YcPehJDKkOOMCliIgIaJLyg5gUeLLma2fcecXmM5Y-mjtIvmwgS84ym08-jhj_hYr2P4YpsGIzT1cIsm83Uq9xtfeo4J1r-OUQ7FxE_syhAjvbFxMuhHQ36wr-kx5JLL7RsyaxXmeWVrG26-c5hgS_pzR-XtSConurdr-kr3KeqUhXYjhebrajzZaVh-fmT38K1iB3r7gJF_YNOONQlJyiw4i6vTOWRNIuhQNL10ujSL5UXB3a8i0CZLPO6kQ4ICflbRE-E-Bhi4iehyL28mCE00CNLr2iJkrmwHeYhn2zDCqKHk_sj2BgWmyTsXLdGwNPIG0LI0KTC1CY41PimKaVKOVruI_OaJe0XAu5YLPuCS3cvSSGFDzhLJkANUMr8rzfCNKyb_tHQbyT8FlC5Cga2Un5iNHThjxCN1kiiWbyT53kHghqWRwFcMZrWWt6KF8WYhMF31YXON7ZetPwK4AP2MQyOng7_UY4-jT3G0k0CPSz8EU87dfaWpZDrtuqsTNF3C2fzHyyXYreIC_K7g1Io3pVKoHGx3kzTrZ8SqjMgl3U1bUlt1swDqFf9rozlv-qxLCGPZcwLRv6ZlgU6Cy78B9bliMXz9O-GmSUEzOsEdDrxBXDzNkQ5LZwgTIIdulV3Ti2YpKMWltkgF_ugV-Nlx8BmXto13n6qqGWvKWNrO7cVXKBeXmF4_OnVk8eHTqBzO2DJWl6jaMuWGiyIhqG7TOSi9G97k0tB5LWWFcyWQodr6iBqbZ5Kf0ERpXd20URrHpyumjhV2bH_w1sDiBFFtliUhJPX69LxHPn_23xIZAn6mJsLxptH_RawP87M2m0Hs91cysbWePBmio8JeUI3bdxalBCnl4cRJhNMQ4yoaEkLe-BIWKxcDUXfbBWovyMYnVzK1tUNMKXBKVtiE=",
+ "summary": [
+ {
+ "type": "summary_text",
+ "text": "**Checking weather in Florence**\n\nThe user is asking about the weather in Florence, Italy, which is a common request. I know I can use the weather tool directly, specifically with the location string \"Florence, Italy.\" There's no need to complicate things with multiple tools for this task. I'll just call the functions.weather tool and then present the result to the user. It's straightforward!"
+ }
+ ]
+ },
+ {
+ "id": "fc_08e75323d01317c301690399fc62bc8190b80c10a99849920f",
+ "type": "function_call",
+ "status": "completed",
+ "arguments": "{\"location\":\"Florence, Italy\"}",
+ "call_id": "call_Frvkxe2RXaW1CTvkYPyl0U68",
+ "name": "weather"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "high",
+ "summary": "detailed"
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 63,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 22,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 85
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 6.70119525s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2549
+ host: ""
+ body: '{"store":false,"include":["reasoning.encrypted_content"],"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence, Italy?","type":"input_text"}],"role":"user"},{"id":"rs_08e75323d01317c301690399f759088190a37f017516202cb2","summary":[{"text":"**Checking weather in Florence**\n\nThe user is asking about the weather in Florence, Italy, which is a common request. I know I can use the weather tool directly, specifically with the location string \"Florence, Italy.\" There''s no need to complicate things with multiple tools for this task. I''ll just call the functions.weather tool and then present the result to the user. It''s straightforward!","type":"summary_text"}],"encrypted_content":"gAAAAABpA5n8UjdGuSzFx6uvW1lDRxxYfY3gisRCV-3fmThjXt28KBNtZygO2FLKsTDYK4GGvbbqBGkaDynHzJFsQBMjvIyjkiLCdu8peexsbHa9xfp_cWzTgMxBsqQK2CDGxcXqokVV1V4u71ZWHvcV7RzevmhbxOn48CoA7FjOZBvyk2C9uCUh2NJs-GQeWP1zXFjDTcJS-_jZOUNxAw4COewYXTv0FHblhMbM9B61tnoflu6S4Xm_7qrWAuBtP9KSqEJQNCRCkRUtVfVThnG7u33pTQJGnd1YcPehJDKkOOMCliIgIaJLyg5gUeLLma2fcecXmM5Y-mjtIvmwgS84ym08-jhj_hYr2P4YpsGIzT1cIsm83Uq9xtfeo4J1r-OUQ7FxE_syhAjvbFxMuhHQ36wr-kx5JLL7RsyaxXmeWVrG26-c5hgS_pzR-XtSConurdr-kr3KeqUhXYjhebrajzZaVh-fmT38K1iB3r7gJF_YNOONQlJyiw4i6vTOWRNIuhQNL10ujSL5UXB3a8i0CZLPO6kQ4ICflbRE-E-Bhi4iehyL28mCE00CNLr2iJkrmwHeYhn2zDCqKHk_sj2BgWmyTsXLdGwNPIG0LI0KTC1CY41PimKaVKOVruI_OaJe0XAu5YLPuCS3cvSSGFDzhLJkANUMr8rzfCNKyb_tHQbyT8FlC5Cga2Un5iNHThjxCN1kiiWbyT53kHghqWRwFcMZrWWt6KF8WYhMF31YXON7ZetPwK4AP2MQyOng7_UY4-jT3G0k0CPSz8EU87dfaWpZDrtuqsTNF3C2fzHyyXYreIC_K7g1Io3pVKoHGx3kzTrZ8SqjMgl3U1bUlt1swDqFf9rozlv-qxLCGPZcwLRv6ZlgU6Cy78B9bliMXz9O-GmSUEzOsEdDrxBXDzNkQ5LZwgTIIdulV3Ti2YpKMWltkgF_ugV-Nlx8BmXto13n6qqGWvKWNrO7cVXKBeXmF4_OnVk8eHTqBzO2DJWl6jaMuWGiyIhqG7TOSi9G97k0tB5LWWFcyWQodr6iBqbZ5Kf0ERpXd20URrHpyumjhV2bH_w1sDiBFFtliUhJPX69LxHPn_23xIZAn6mJsLxptH_RawP87M2m0Hs91cysbWePBmio8JeUI3bdxalBCnl4cRJhNMQ4yoaEkLe-BIWKxcDUXfbBWovyMYnVzK1tUNMKXBKVtiE=","type":"reasoning"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_Frvkxe2RXaW1CTvkYPyl0U68","name":"weather","type":"function_call"},{"call_id":"call_Frvkxe2RXaW1CTvkYPyl0U68","output":"40 C","type":"function_call_output"}],"model":"gpt-5-mini","reasoning":{"effort":"high","summary":"auto"},"tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 5385
+ body: |-
+ {
+ "id": "resp_08e75323d01317c301690399fcde608190a0fecfea7cd36d21",
+ "object": "response",
+ "created_at": 1761843708,
+ "status": "completed",
+ "background": false,
+ "content_filters": null,
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": null,
+ "max_tool_calls": null,
+ "model": "gpt-5-mini",
+ "output": [
+ {
+ "id": "rs_08e75323d01317c301690399fd3850819098dd485846bdffdb",
+ "type": "reasoning",
+ "encrypted_content": "gAAAAABpA5oG_ll7ThMwW-18Yqi-ei4hs-px3XUGHH6dTl3eCweNP0omlO0V4VGombiAXb7GT_ScFOlhCGpQOY75MRsi2MvZrQ7HyAezH7dgX6YHPxYf_x9ryT028XZh82ZCjgnGj0xV6b2AhLZCo1sVIh3swqeNGgb8mnh5Ia1IByHnHXUEX7rZ525mvIUYhnwFh-AyE_cRbwC48d4dY8LwW_DBAjaHwkFKrL0Xc8Fwh6E9I8J2dDorTV6lbyNmhedpKcEUv9fHXQabANFFkubpOCDALvLPDsrDDRaTiGQw4WyePEPB531bqVZ0DXtlLsO6pyT-Cll4MM3WqMhEAIiEasnfbaidPeXXQzugFagSs--PBcoJ4Y616lc-kMELAuo27Gm2C1gNPWxGHePry7zCMj6gxouUZsxuOpCozOg1XRFlT2BctxSdGOU36swqyW4jjpyDDH0I21iSeRI6HY-wkjMrq-iaQRkrZm_WmVj8yInYLMb_g6THvjgzTeUWIxrFJYUk3NhOT4OaZ_b6NcLp0GatfLDQb_aXyPu1vjLX2oJhHjb7TWSrQYZiYmRR4qoTd9o3TMquC-M85vgsz-DkHlHN0fJUs3CXtwEzPPbupl0Wiyu4CF4EPvF3vxSYQf2tCLkbybVnJrdfPmmFPSzgeYFtf6T-M_Z26hUjJD2eRQ8qeMJurvDPE2TL_w6XSJPyFj0Tlzl_BcHVjkt3BvWP6SgKd4xxhde6O1cfU_gOlL91w879D-Z3OHDYCpkhN1f9GfdnH-CAGkmcLfAXcvPh5lHvLzpY1k2TXWeDwEsI0lj_ravjBNBjoXBIEZl3DG4VoWPrpLib-vhavHxNtwm-TEM8NOvy-fYtucz_yGMKFxhwWkcMcSNM9UpWrXcpp7iaSiXcbgZZgmuFXEqhaSQEKEeMOATMH_6CYzAh6wuRKRVisGOn6ZHsFvit0dMQxTPGc8zh1R-69kepkTNjLKC7U4cs1geqBQQyaO-A9hgUQX89zGXTdkmPRSfjOgShS3LQo90s7UGkUMlOBwCMESliwfjY_lwS8dSJ0t-qkYahcYAVzNqGkUh92eSuwwk94WDYGXTBZvKUUQKKJWb7xP2tyLCXflv4BGtO19_44tyLG68YmU-r82b-z_U_Rj77m1Wsz8TIuYY2fX4DrqSE5aV3Wbn2AYbAHAmNRz_UI3rEezN6wERgb9fyvcmzl4EV5YmsZuh_D28paVc8w56Qhki3VfnFQvPrGlCqdukBIWCByU2NhjUYix_n6-Iv2BfMmZTANDQH49m4eEOs0rxvy0hNBaa-wrAMCPBDJU6NF7FnaV7DYzXChz2dv8f8p3MndlD_e0JvCq3EnQdPIF0dmwK-gka_WZf45QrIX8gMlQLeeeDj-7uA1DpzjZsV44bK8mshVJJ_wz1WMTF23bxhJ3ADdpQPOWUJD9Ol3qUurBrA0NbtF1clZt2tdiuVOUMwEcs5jLy0Y8PUql_-9Uw8izYzwGWnwqLb8VBPfLTVnoRMnMVEP07Nhno3_L4yHJFPEWLKdawNBk6cDusX-lk0V-BdkYygJN7tPq04PP3puq5UccHkxh8ECBxwscKXtCUiBjYtGAVy3gcW2xgDBvkm42Aij9Z3ICftjlJIZLp5TFFGtb_PwpgCDSVSl31untlw3O2HkyVaj1IqWBx7Yvy3g7SMhRvtEZCzwIMFNAy7xnYOcvXjOgYk2btpt5vjrp8vnjkRsSx7VaIMRQsAKLIINDkqXgXjt0AkU90mF8__p_str-PfI1MyTyKE4E_VzlFSKcARe9v5oSVjBH39gwVd6PZW0E7hBcYybeasmnvWRoIfkqbagIumUHg5aCdDpqOrU4gisyw6r5b6ezBSP7lh4KceR-NNVdDcPI3vn3k7MiElIwEfUjwwh9AmsPCloh1et8d9uepGCFP6ehEtGUKvRbil17TZcUOq8DDGCfXAGKSRui8W_GU5hhOJBrDpjxZGvmH-29hfviPHZGtPNTi6zQWqcCxSpxDRyeNWmvp5IMf8Kz7ej6Ve6wHahVOBm_wM-8zwZI5yEazSWZRTYqaWY5vnPs--SsnS2R0lOd1oLHybGZTKW0-YXmqWDrIcnrA0fq7UsCkuNBgzew_9fZg2NIGvukMfBAtBTq-FQ9DM2-mnDPlNXvMRswTga-uV_Z2UQNjvEnY8xn_7ZnUGeGpVWjbHg4GXW5zV9f5aAdtV452YKqQ55JzvR5yJ47lg3EphgHR-5_vOvr-Bl-kEm40oEo8zvNquBcxJ9mvZ478WGGbvGzhOK065YN-nZD91JNUQcALSO_hF_FE4Tk_VvZmFztcRU3nOnF3mHXWe-wJ30UCzKuLNkL9keemUUiAylMvkec0_gR-SxmPyzYvI9XuYc8TYV1xrEWx37wI89fihJeXfS5fmUJEPkPpFq-W704mdXqdG873I15fr-HGx_hcqH1QA6x-8-JtwN-5Se9Pi-iq4UN10T5K95XVgadJbeehLim4Fjxf_SZSyb0rYVnP57h-u1Orh-mwlNNLcf4J_5OQ1h7MWE5DV_gQKhv4Myr3zHVmN6mweUx22fwW6H9AMwfpaEwA5B5feOz8Op94hSgQvmmA6mk5I2CuRZ3H2d0i1b4su4oCcVnW7",
+ "summary": [
+ {
+ "type": "summary_text",
+ "text": "**Crafting weather update**\n\nI want to offer the user a gentle choice: \"Would you like the forecast or hourly updates?\" I think a good response could be: \"Right now it's 40\u00b0C (104\u00b0F) in Florence, Italy \u2014 quite hot!\" I should advise them to stay hydrated, limit outdoor activities during peak sun, wear light clothing, and seek shade or air conditioning. I\u2019ll ask if they want a 7-day forecast or hourly temperatures. Keeping it concise is key!"
+ }
+ ]
+ },
+ {
+ "id": "msg_08e75323d01317c30169039a058e308190a79d0f0c4e834ad2",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "Right now it\u2019s 40 \u00b0C (104 \u00b0F) in Florence, Italy \u2014 very hot. Stay hydrated, avoid strenuous outdoor activity during midday, wear light clothing and use sun protection. Would you like an hourly forecast or a multi-day outlook?"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "high",
+ "summary": "detailed"
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 159,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 313,
+ "output_tokens_details": {
+ "reasoning_tokens": 256
+ },
+ "total_tokens": 472
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 9.847531375s
diff --git a/internal/fantasy/providertests/testdata/TestAzureThinking/azure-gpt-5-mini/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestAzureThinking/azure-gpt-5-mini/thinking-streaming.yaml
new file mode 100644
index 000000000..07ed45a77
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureThinking/azure-gpt-5-mini/thinking-streaming.yaml
@@ -0,0 +1,217 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 515
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"gpt-5-mini","reasoning_effort":"high","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}]}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"content":null,"refusal":null,"role":"assistant","tool_calls":[{"function":{"arguments":"","name":"weather"},"id":"call_IXyDXemyXlFWVdGVguHr5Sbe","index":0,"type":"function"}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843005,"id":"chatcmpl-CWQ8bl0XuL6BClGD5vgNEVqB7FDJX","model":"gpt-5-mini-2025-08-07","obfuscation":"uaMd1T9RcrzY1","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"{\""},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843005,"id":"chatcmpl-CWQ8bl0XuL6BClGD5vgNEVqB7FDJX","model":"gpt-5-mini-2025-08-07","obfuscation":"7hL","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"location"},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843005,"id":"chatcmpl-CWQ8bl0XuL6BClGD5vgNEVqB7FDJX","model":"gpt-5-mini-2025-08-07","obfuscation":"It5BrwApZDAmaZ","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"\":\""},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843005,"id":"chatcmpl-CWQ8bl0XuL6BClGD5vgNEVqB7FDJX","model":"gpt-5-mini-2025-08-07","obfuscation":"r","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"Flor"},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843005,"id":"chatcmpl-CWQ8bl0XuL6BClGD5vgNEVqB7FDJX","model":"gpt-5-mini-2025-08-07","obfuscation":"Nc","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"ence"},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843005,"id":"chatcmpl-CWQ8bl0XuL6BClGD5vgNEVqB7FDJX","model":"gpt-5-mini-2025-08-07","obfuscation":"7r","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":","},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843005,"id":"chatcmpl-CWQ8bl0XuL6BClGD5vgNEVqB7FDJX","model":"gpt-5-mini-2025-08-07","obfuscation":"MGNaY","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":" Italy"},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843005,"id":"chatcmpl-CWQ8bl0XuL6BClGD5vgNEVqB7FDJX","model":"gpt-5-mini-2025-08-07","obfuscation":"","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"\"}"},"index":0}]},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843005,"id":"chatcmpl-CWQ8bl0XuL6BClGD5vgNEVqB7FDJX","model":"gpt-5-mini-2025-08-07","obfuscation":"t4l","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{},"finish_reason":"tool_calls","index":0,"logprobs":null}],"created":1761843005,"id":"chatcmpl-CWQ8bl0XuL6BClGD5vgNEVqB7FDJX","model":"gpt-5-mini-2025-08-07","obfuscation":"5GHK","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[],"created":1761843005,"id":"chatcmpl-CWQ8bl0XuL6BClGD5vgNEVqB7FDJX","model":"gpt-5-mini-2025-08-07","obfuscation":"3b8TlKRFFcjm","object":"chat.completion.chunk","system_fingerprint":null,"usage":{"completion_tokens":90,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":64,"rejected_prediction_tokens":0},"prompt_tokens":145,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":235}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 3.489423709s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 767
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"call_IXyDXemyXlFWVdGVguHr5Sbe","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_IXyDXemyXlFWVdGVguHr5Sbe","role":"tool"}],"model":"gpt-5-mini","reasoning_effort":"high","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}]}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"content":"","refusal":null,"role":"assistant"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"hqlJnDYyrDUmTx","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"Right"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"5A80nHsvZg0","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" now"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"pX2s8jfZcU1h","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" in"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"1ybxhw06Hfpby","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" Florence"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"gcR9DkF","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":","},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"D2DmY7D1iKZkzEF","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" Italy"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"pA3OdoLbWX","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" it"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"FVQsr3xpMeReg","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"ās"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"PSNGyio1hHOhNT","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" "},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"iE6VePqqFACIeLn","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"40"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"Rs3BzgW1wLZNIW","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"°C"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"ugO91Rmooib7wK","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" ("},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"5EcQG5MstC1H58","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"104"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"ebUiPqCHw4PW4","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"°F"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"XyYWjrDdGjX7mS","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":")."},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"iH7YF3pg3D3L33","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" That"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"I5GoUtCaHEX","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"ās"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"xjoz4yMu3sXGBP","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" very"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"QHiSfUaVvzE","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" hot"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"wPV94GSdXzr7","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" ā"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"84lO5nXdrFIp5G","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" stay"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"CDQaPucwRMR","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" hydrated"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"fSP3D9L","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":","},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"qtHg6eRLgch21pn","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" avoid"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"wCkXcTtorp","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" strenuous"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"hgC8ML","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" outdoor"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"M23NRD0u","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" activity"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"ApabYQB","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" in"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"Aenr53JRRPDdr","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" the"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"kTm47OyAiKTS","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" midday"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"AlKC23Znm","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" sun"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"gIzjaYM1QWwj","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":","},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"QtnqPe70AktHxrM","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" and"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"h81EcsaVsSqI","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" use"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"SvOxON98klvJ","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" sunscreen"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"qMRVqU","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" and"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"RDjFdl1tTlRm","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" light"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"bQGdkZmkH8","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" clothing"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"BZ9Sltx","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"."},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"ZSpi8mAFjtobvtl","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" Would"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"UbQ3B1FFbN","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" you"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"e8oaxQDtn0fW","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" like"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"QqzM2MPGian","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" an"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"S5u4WZAvtcvxb","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" hourly"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"qR1WcP67Z","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" forecast"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"G3efZ8d","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":","},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"AvIShW11ecSB5Kb","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" a"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"HNipO50l8mXVi2","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" multi"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"YSpm46cWkO","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"-day"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"yYbxPZ7Hsog4","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" outlook"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"4USPZhVo","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":","},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"hyfnSPDzog3tKEg","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" or"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"y3IpD0w7NTJBT","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" tips"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"vEkBNMqMIAt","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" for"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"WBu1A17CzN8A","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" staying"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"jDUk3NdM","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" safe"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"KF3kOIenFqY","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" in"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"ROhDQwfK2fAse","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" the"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"iU4K1xyEir5W","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" heat"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"p8izEBCrC84","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"?"},"finish_reason":null,"index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"WBHU0VQw0fnm21S","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{},"finish_reason":"stop","index":0,"logprobs":null}],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"QL3mWfmvPv","object":"chat.completion.chunk","system_fingerprint":null,"usage":null}
+
+ data: {"choices":[],"created":1761843008,"id":"chatcmpl-CWQ8exhWrGdpsztLDjaAKDMrsAT72","model":"gpt-5-mini-2025-08-07","obfuscation":"X2xZyK0wIK","object":"chat.completion.chunk","system_fingerprint":null,"usage":{"completion_tokens":518,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":448,"rejected_prediction_tokens":0},"prompt_tokens":176,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":694}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 10.8719895s
diff --git a/internal/fantasy/providertests/testdata/TestAzureThinking/azure-gpt-5-mini/thinking.yaml b/internal/fantasy/providertests/testdata/TestAzureThinking/azure-gpt-5-mini/thinking.yaml
new file mode 100644
index 000000000..395f807ab
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureThinking/azure-gpt-5-mini/thinking.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 461
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"gpt-5-mini","reasoning_effort":"high","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 1051
+ body: |
+ {"choices":[{"content_filter_results":{},"finish_reason":"tool_calls","index":0,"logprobs":null,"message":{"annotations":[],"content":null,"refusal":null,"role":"assistant","tool_calls":[{"function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"id":"call_DUlGZ00SpDPsuwZGXVWQyFFW","type":"function"}]}}],"created":1761842994,"id":"chatcmpl-CWQ8Q4JDZwBrx3DQx4ZSZHRxmmDZC","model":"gpt-5-mini-2025-08-07","object":"chat.completion","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"system_fingerprint":null,"usage":{"completion_tokens":90,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":64,"rejected_prediction_tokens":0},"prompt_tokens":145,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":235}}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.366893959s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 713
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"call_DUlGZ00SpDPsuwZGXVWQyFFW","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_DUlGZ00SpDPsuwZGXVWQyFFW","role":"tool"}],"model":"gpt-5-mini","reasoning_effort":"high","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 1344
+ body: |
+ {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"protected_material_text":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"finish_reason":"stop","index":0,"logprobs":null,"message":{"annotations":[],"content":"It's currently 40°C (104°F) in Florence, Italy ā quite hot. Stay hydrated and avoid prolonged sun exposure during peak hours. Would you like the hourly forecast or the outlook for the next few days?","refusal":null,"role":"assistant"}}],"created":1761842997,"id":"chatcmpl-CWQ8TuzLOjG9vatDbmlnZ6mNdo29i","model":"gpt-5-mini-2025-08-07","object":"chat.completion","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"system_fingerprint":null,"usage":{"completion_tokens":309,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":256,"rejected_prediction_tokens":0},"prompt_tokens":176,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":485}}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 7.677985209s
diff --git a/internal/fantasy/providertests/testdata/TestAzureThinking/azure-grok-3-mini/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestAzureThinking/azure-grok-3-mini/thinking-streaming.yaml
new file mode 100644
index 000000000..754d7faaa
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureThinking/azure-grok-3-mini/thinking-streaming.yaml
@@ -0,0 +1,1667 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 516
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"grok-3-mini","reasoning_effort":"high","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}]}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"First","role":"assistant"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" asking"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" about"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" in"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Florence"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Italy"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" have"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" an"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" available"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" called"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"weather"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\""},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" that"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" can"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" get"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" information"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" for"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" location"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"The"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" description"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Get"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" information"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" for"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" location"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\"."},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" The"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameters"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" require"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"location"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\""},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" which"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" string"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" describing"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" city"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"In"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" this"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" query"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" has"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" provided"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Florence"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Italy"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\","},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" which"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" clearly"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" specifies"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" city"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" and"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" country"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" This"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" matches"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" required"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameter"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" for"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"weather"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\""},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"All"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" required"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameters"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" are"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" provided"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" location"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Florence"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Italy"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\"."},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" don't"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" need"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" infer"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" anything"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" else"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":";"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" it's"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" straightforward"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"According"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" instructions"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" if"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user's"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" query"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" can"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" be"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" addressed"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" using"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" an"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" available"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" and"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" all"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" required"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameters"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" are"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" provided"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" or"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" obviously"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" infer"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"able"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" trigger"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" in"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" JSON"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" format"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" within"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \u003c"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"function"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"_call"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\u003e\u003c/"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"function"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"_call"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\u003e"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" tags"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"The"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" logical"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" next"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" step"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"weather"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\""},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" with"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" location"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameter"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"I"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" not"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" make"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" my"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" verbose"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":";"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" keep"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" it"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" clear"},"index":0}],"created":1761843026,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Since"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I'm"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" calling"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" don't"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" need"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" add"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" extra"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" text"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" unless"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" necessary"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" The"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" instructions"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" say"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" use"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \u003c"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"function"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"_call"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\u003e"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" tag"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" only"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" when"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" deciding"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" and"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" in"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" this"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" case"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" that's"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" appropriate"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"After"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" calling"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" in"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" multi"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"-turn"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" conversation"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" might"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" need"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" handle"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" but"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" for"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" now"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" immediate"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" action"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Function"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" format"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \u003c"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"function"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"_call"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\u003e{\""},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"action"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\":"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"weather"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\","},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"action"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"_input"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\":"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" {\""},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"location"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\":"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Florence"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Italy"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\""},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"}}\u003c/"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"function"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"_call"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\u003e\n\n"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"That"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" seems"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" correct"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"I"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" don't"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" need"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" ask"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" for"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" clarification"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" because"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" matches"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" and"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameters"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" are"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" clear"},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"tool_calls":[{"function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"id":"call_79034109","index":0,"type":"function"}]},"index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{},"finish_reason":"tool_calls","index":0}],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[],"created":1761843027,"id":"8b92da10-d7cc-4c57-af61-1135ddc68f6d_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9","usage":{"completion_tokens":27,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":317,"rejected_prediction_tokens":0},"num_sources_used":0,"prompt_tokens":288,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0,"image_tokens":0,"text_tokens":288},"total_tokens":632}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 244.989833ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 736
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"call_79034109","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_79034109","role":"tool"}],"model":"grok-3-mini","reasoning_effort":"high","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}]}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"First","role":"assistant"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" asked"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" about"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" in"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Florence"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Italy"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" have"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" an"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" available"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" called"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"weather"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\""},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" that"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" can"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" retrieve"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" information"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" for"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" given"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" location"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"The"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" requires"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"location"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\""},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameter"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" which"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" described"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" as"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"the"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" city"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\"."},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" The"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" provided"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Florence"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Italy"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\","},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" which"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" clearly"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" specifies"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" city"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" and"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" country"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" so"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" all"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" required"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameters"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" are"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" present"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" and"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" infer"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"able"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"According"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" system"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" prompt"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" if"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user's"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" query"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" can"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" be"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" addressed"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" using"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" an"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" available"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" and"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" all"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" required"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" parameters"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" are"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" provided"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" trigger"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" in"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" specified"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" JSON"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" format"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" within"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \u003c"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"function"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"_call"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\u003e"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" tags"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"I"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" already"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" made"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" in"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" my"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" previous"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \u003c"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"function"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"_call"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\u003e{\""},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"action"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\":"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"weather"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\","},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"action"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"_input"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\":"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" {\""},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"location"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\":"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Florence"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Italy"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\""},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"}}\u003c/"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"function"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"_call"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\u003e\n\n"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Now"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" from"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" given"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" as"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Function"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" "},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"40"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" C"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\"."},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" This"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" seems"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" be"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" result"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" of"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843028,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" indicating"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" "},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"40"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" degrees"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Celsius"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"In"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" multi"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"-turn"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" conversation"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" need"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" continue"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" calling"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" relevant"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" functions"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" if"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" needed"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" fulfill"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user's"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" request"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" However"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user's"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" request"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" was"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" get"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" and"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" has"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" now"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" provided"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" information"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" ("},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"40"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" C"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":")."},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" So"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" request"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" likely"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" fulfilled"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"The"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" system"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" prompt"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" says"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"continue"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" calling"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" relevant"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" functions"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" advance"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user's"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" request"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" until"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" either"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user's"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" request"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" fully"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" fulfilled"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" or"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" you"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" need"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" more"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" information"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\"\n\n"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Since"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" information"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" has"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" been"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" retrieved"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" don't"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" need"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" any"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" more"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" functions"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" now"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" provide"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" clear"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" non"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"-"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"verbose"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" with"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" information"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"The"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" prompt"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" also"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" emphasizes"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Keep"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" your"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" clear"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":";"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" please"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" do"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" not"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" make"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" your"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" verbose"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"!\""},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" So"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" be"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" concise"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Additionally"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"40"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" C"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\","},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" which"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" straightforward"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" but"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" present"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" it"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" in"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" a"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" user"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"-friendly"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" way"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" perhaps"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" confirming"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" location"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"My"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" not"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" include"},"index":0}],"created":1761843029,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" any"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" more"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" calls"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" unless"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" needed"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Here"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" no"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" more"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" calls"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" are"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" necessary"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Final"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" structure"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":\n"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"-"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Since"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" call"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" has"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" been"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" made"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" and"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" responded"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" to"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" output"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" result"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" clearly"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"-"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Response"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" be"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" direct"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":":"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" e"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".g"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".,"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"The"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" weather"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" in"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Florence"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":","},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Italy"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" "},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"40"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"°C"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\"\n\n"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"The"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" function"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" \""},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"40"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" C"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"\","},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" which"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" assume"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" means"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" "},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"40"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" degrees"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" Celsius"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" I"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" should"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" use"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" standard"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" notation"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" for"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" clarity"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":".\n\n"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"Ensure"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" the"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" response"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" is"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" not"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":" verbose"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{"reasoning_content":"."},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"The"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" weather"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" in"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" Florence"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":","},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" Italy"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" is"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" "},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"40"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"°C"},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"."},"index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[{"content_filter_results":{},"delta":{},"finish_reason":"stop","index":0}],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9"}
+
+ data: {"choices":[],"created":1761843030,"id":"ef1dea44-a8a8-4042-b657-b7ea36af2ea9_sidecar","model":"grok-3-mini-high","object":"chat.completion.chunk","system_fingerprint":"fp_d33f0040b9","usage":{"completion_tokens":11,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":466,"rejected_prediction_tokens":0},"num_sources_used":0,"prompt_tokens":332,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0,"image_tokens":0,"text_tokens":332},"total_tokens":809}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 264.74125ms
diff --git a/internal/fantasy/providertests/testdata/TestAzureThinking/azure-grok-3-mini/thinking.yaml b/internal/fantasy/providertests/testdata/TestAzureThinking/azure-grok-3-mini/thinking.yaml
new file mode 100644
index 000000000..d74c80036
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestAzureThinking/azure-grok-3-mini/thinking.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 462
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"grok-3-mini","reasoning_effort":"high","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {"choices":[{"content_filter_results":{},"finish_reason":"tool_calls","index":0,"logprobs":null,"message":{"content":"","reasoning_content":"First, the user is asking about the weather in Florence, Italy. I have an available function called \"weather\" that can get weather information for a location.\n\nThe function description is: \"Get weather information for a location\". The parameters require a \"location\" which is a string describing the city.\n\nIn this query, the user has provided \"Florence, Italy\", which clearly specifies the city and country. This should be sufficient for the \"location\" parameter.\n\nAll required parameters are provided and inferable. The location is given as \"Florence, Italy\", so I can use that directly.\n\nI should call the function if it can advance the user's request. Here, calling the \"weather\" function with the location will directly provide the weather information, fulfilling the user's query.\n\nThe response format for function calls is specific: I need to use \u003cfunction_call\u003e tags with JSON format, like \u003cfunction_call\u003e{\"action\": \"function_name\", \"action_input\": {\"parameter\": \"argument\"}}\u003c/function_call\u003e.\n\nSo, for this, the action is \"weather\", and the action_input should have \"location\" set to \"Florence, Italy\".\n\nAfter calling the function, in a multi-turn conversation, I might need to handle the response, but the system prompt says to continue calling functions until the request is fulfilled. However, once I call this function, it should return the weather data, and I can then respond with that information. But the function call itself will handle retrieving the data.\n\nThe prompt says: \"You can call functions to retrieve information or perform actions.\" And \"trigger a function call in JSON format within \u003cfunction_call\u003e\u003c/function_call\u003e tags.\"\n\nI should not make my response verbose; keep it clear.\n\nSince this is the logical next step, I should just make the function call without additional text, unless needed. The prompt says: \"Keep your response to user clear; please do not make your response verbose!\" And \"If there is anything unclear, ask the user for clarification.\"\n\nIn this case, everything is clear, so no need to ask for clarification.\n\nMy response should only contain the function call in the specified format.\n\nFinally, format it as: \u003cfunction_call\u003e{\"action\": \"weather\", \"action_input\": {\"location\": \"Florence, Italy\"}}\u003c/function_call\u003e\n\nThat seems correct.","refusal":null,"role":"assistant","tool_calls":[{"function":{"arguments":"{\"location\":\"Florence, Italy\"}","call_id":null,"name":"weather"},"id":"call_78100819","type":"function"}]},"stop_reason":null}],"created":1761843020,"id":"26c2d70b-1783-4e27-bd1c-20e7eea8d924_sidecar","model":"grok-3-mini-high","object":"chat.completion","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"usage":{"audio_prompt_tokens":0,"completion_tokens":27,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":464,"rejected_prediction_tokens":0},"num_sources_used":0,"prompt_tokens":288,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0,"image_tokens":0,"text_tokens":288},"total_tokens":779}}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.311565s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 682
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"call_78100819","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_78100819","role":"tool"}],"model":"grok-3-mini","reasoning_effort":"high","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://fantasy-playground-resource.openai.azure.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"protected_material_code":{"filtered":false,"detected":false},"protected_material_text":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"finish_reason":"stop","index":0,"logprobs":null,"message":{"content":"The weather in Florence, Italy is 40°C.","reasoning_content":"First, the user asked: \"What's the weather in Florence, Italy?\" This directly matches the available function \"weather\", which requires a \"location\" parameter.\n\nI have already decided to call the function in my initial response, as shown in the conversation history. Now, the function call was made, and the response from the function is \"40 C\". I need to handle this in my response.\n\nAs a helpful assistant, after a function call, I should provide the information to the user in a clear and non-verbose way. The function call returned \"40 C\", which I assume means 40 degrees Celsius. I should present this information directly.\n\nThe system prompt says: \"Keep your response to user clear; please do not make your response verbose!\" So, I need to be concise.\n\nAlso, the prompt indicates that in multi-turn conversations, I should continue calling relevant functions if needed, but in this case, the function has been called and I have the result, so I can now respond with the information.\n\nThere's no need for another function call here because the query is fulfilled with the weather information.\n\nMy response should simply state the weather based on the function's output.\n\nFinal response structure: Since the function call has been executed and I have the result, I should output the weather information clearly.","refusal":null,"role":"assistant","tool_calls":null},"stop_reason":null}],"created":1761843024,"id":"3b2bc93e-a7e0-4852-924b-9482b44ec310_sidecar","model":"grok-3-mini-high","object":"chat.completion","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"usage":{"audio_prompt_tokens":0,"completion_tokens":11,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":262,"rejected_prediction_tokens":0},"num_sources_used":0,"prompt_tokens":332,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0,"image_tokens":0,"text_tokens":332},"total_tokens":605}}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.801076291s
diff --git a/internal/fantasy/providertests/testdata/TestBedrockBasicAuth/simple.yaml b/internal/fantasy/providertests/testdata/TestBedrockBasicAuth/simple.yaml
new file mode 100644
index 000000000..78bdadacf
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestBedrockBasicAuth/simple.yaml
@@ -0,0 +1,32 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 211
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Say hi in Portuguese","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-sonnet-20240229-v1%3A0/invoke
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 248
+ body: '{"id":"msg_bdrk_01SLPR8DXPtQG4ryAsmuQrA9","type":"message","role":"assistant","model":"claude-3-sonnet-20240229","content":[{"type":"text","text":"OlĆ”!"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":16,"output_tokens":7}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.764905916s
diff --git a/internal/fantasy/providertests/testdata/TestBedrockBasicAuth/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestBedrockBasicAuth/simple_streaming.yaml
new file mode 100644
index 000000000..467575035
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestBedrockBasicAuth/simple_streaming.yaml
@@ -0,0 +1,76 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 211
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Say hi in Portuguese","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-sonnet-20240229-v1%3A0/invoke-with-response-stream
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: !!binary |
+ AAABvQAAAEunJ1hxCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcG
+ xpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJs
+ SWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZl
+ ltUnlhMTh3TVVjM1ZUWXlaMU4zYWxwU1ptMVVTMkpDWjNGQmExSWlMQ0owZVhCbElqb2li
+ V1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWV
+ hWa1pTMHpMWE52Ym01bGRDMHlNREkwTURJeU9TSXNJbU52Ym5SbGJuUWlPbHRkTENKemRH
+ OXdYM0psWVhOdmJpSTZiblZzYkN3aWMzUnZjRjl6WlhGMVpXNWpaU0k2Ym5Wc2JDd2lkWE
+ 5oWjJVaU9uc2lhVzV3ZFhSZmRHOXJaVzV6SWpveE5pd2liM1YwY0hWMFgzUnZhMlZ1Y3lJ
+ Nk1uMTlmUT09IiwicCI6ImFiYyJ9vnwv4QAAAPgAAABL/Ghc7Qs6ZXZlbnQtdHlwZQcABW
+ NodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUH
+ AAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5emRHRn
+ lkQ0lzSW1sdVpHVjRJam93TENKamIyNTBaVzUwWDJKc2IyTnJJanA3SW5SNWNHVWlPaUow
+ WlhoMElpd2lkR1Y0ZENJNklpSjlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dX
+ Z3eHl6In2rrhIPAAAA+gAAAEuGqA+NCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQt
+ dHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcy
+ I6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElq
+ b3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaU
+ pQYkNKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQiJ9FHa6UgAA
+ AQ0AAABLt+BQZQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaW
+ NhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElq
+ b2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0
+ k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lMRG9TSjlmUT09Iiwi
+ cCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVIn
+ 3UdODmAAAA9AAAAEs5mLHsCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcA
+ EGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5Sj
+ BlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0pr
+ Wld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUloSW4xOS
+ IsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiJ9l8ofGQAAANMAAABLSnlC+As6
+ ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDT
+ ptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRG
+ OWliRzlqYTE5emRHOXdJaXdpYVc1a1pYZ2lPakI5IiwicCI6ImFiY2RlZmdoaWprbG1ub3
+ BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVlcifUu+MSwAAAEuAAAASzGBBbEL
+ OmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg
+ 06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pYldWemMyRm5a
+ VjlrWld4MFlTSXNJbVJsYkhSaElqcDdJbk4wYjNCZmNtVmhjMjl1SWpvaVpXNWtYM1IxY2
+ 00aUxDSnpkRzl3WDNObGNYVmxibU5sSWpwdWRXeHNmU3dpZFhOaFoyVWlPbnNpYjNWMGNI
+ VjBYM1J2YTJWdWN5STZOMzE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QU
+ JDREVGR0hJSktMTU5PUFFSU1RVViJ9tMfCKgAAAVMAAABLMMMhzws6ZXZlbnQtdHlwZQcA
+ BWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cG
+ UHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2liV1Z6YzJGblpWOXpkRzl3SWl3aVlX
+ MWhlbTl1TFdKbFpISnZZMnN0YVc1MmIyTmhkR2x2YmsxbGRISnBZM01pT25zaWFXNXdkWF
+ JVYjJ0bGJrTnZkVzUwSWpveE5pd2liM1YwY0hWMFZHOXJaVzVEYjNWdWRDSTZOeXdpYVc1
+ MmIyTmhkR2x2Ymt4aGRHVnVZM2tpT2pVMk5Dd2labWx5YzNSQ2VYUmxUR0YwWlc1amVTST
+ ZOVFEyZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQyJ9KKxn3Q==
+ headers:
+ Content-Type:
+ - application/vnd.amazon.eventstream
+ status: 200 OK
+ code: 200
+ duration: 693.876083ms
diff --git a/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-haiku/simple.yaml b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-haiku/simple.yaml
new file mode 100644
index 000000000..bd66b5c69
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-haiku/simple.yaml
@@ -0,0 +1,32 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 211
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Say hi in Portuguese","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-haiku-20240307-v1%3A0/invoke
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 247
+ body: '{"id":"msg_bdrk_019bWLruSqBTAJcMDVgwSMYG","type":"message","role":"assistant","model":"claude-3-haiku-20240307","content":[{"type":"text","text":"OlĆ”!"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":16,"output_tokens":7}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 507.486375ms
diff --git a/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-haiku/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-haiku/simple_streaming.yaml
new file mode 100644
index 000000000..0805a69e5
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-haiku/simple_streaming.yaml
@@ -0,0 +1,69 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 211
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Say hi in Portuguese","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-haiku-20240307-v1%3A0/invoke-with-response-stream
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: !!binary |
+ AAAB3AAAAEsDdQaMCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcG
+ xpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJs
+ SWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZl
+ ltUnlhMTh3TVVaamNqVnRXbk5tY0VGMU1WRkVZbE50Um5Wb01uZ2lMQ0owZVhCbElqb2li
+ V1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWV
+ hWa1pTMHpMV2hoYVd0MUxUSXdNalF3TXpBM0lpd2lZMjl1ZEdWdWRDSTZXMTBzSW5OMGIz
+ QmZjbVZoYzI5dUlqcHVkV3hzTENKemRHOXdYM05sY1hWbGJtTmxJanB1ZFd4c0xDSjFjMk
+ ZuWlNJNmV5SnBibkIxZEY5MGIydGxibk1pT2pFMkxDSnZkWFJ3ZFhSZmRHOXJaVzV6SWpv
+ MWZYMTkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0wiff
+ MMltsAAAEVAAAAS+dwjCYLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQ
+ YXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMG
+ VYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOXpkR0Z5ZENJc0ltbHVaR1Y0SWpvd0xDSmpi
+ MjUwWlc1MFgySnNiMk5ySWpwN0luUjVjR1VpT2lKMFpYaDBJaXdpZEdWNGRDSTZJaUo5Zl
+ E9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BR
+ UlNUVVZXWFlaMDEyIn3xsEfkAAABDwAAAEvNIAMFCzpldmVudC10eXBlBwAFY2h1bmsNOm
+ NvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50
+ eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbW
+ x1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5S
+ bGVIUWlPaUpQYk1PaElTSjlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eH
+ l6QUJDREVGR0hJSktMTU5PUFFSUyJ9ufbmngAAANIAAABLdxlrSAs6ZXZlbnQtdHlwZQcA
+ BWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cG
+ UHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5emRH
+ OXdJaXdpYVc1a1pYZ2lPakI5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QU
+ JDREVGR0hJSktMTU5PUFFSU1RVViJ9nolvDwAAASIAAABL9HHosAs6ZXZlbnQtdHlwZQcA
+ BWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cG
+ UHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2liV1Z6YzJGblpWOWtaV3gwWVNJc0lt
+ UmxiSFJoSWpwN0luTjBiM0JmY21WaGMyOXVJam9pWlc1a1gzUjFjbTRpTENKemRHOXdYM0
+ 5sY1hWbGJtTmxJanB1ZFd4c2ZTd2lkWE5oWjJVaU9uc2liM1YwY0hWMFgzUnZhMlZ1Y3lJ
+ Nk4zMTkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKIn3PqX
+ VIAAABcgAAAEvMYid7CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFw
+ cGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWE
+ JsSWpvaWJXVnpjMkZuWlY5emRHOXdJaXdpWVcxaGVtOXVMV0psWkhKdlkyc3RhVzUyYjJO
+ aGRHbHZiazFsZEhKcFkzTWlPbnNpYVc1d2RYUlViMnRsYmtOdmRXNTBJam94Tml3aWIzVj
+ BjSFYwVkc5clpXNURiM1Z1ZENJNk55d2lhVzUyYjJOaGRHbHZia3hoZEdWdVkza2lPalEx
+ TVN3aVptbHljM1JDZVhSbFRHRjBaVzVqZVNJNk5ETXpmWDA9IiwicCI6ImFiY2RlZmdoaW
+ prbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2NyJ9
+ erLFww==
+ headers:
+ Content-Type:
+ - application/vnd.amazon.eventstream
+ status: 200 OK
+ code: 200
+ duration: 586.543542ms
diff --git a/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-haiku/tool.yaml b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-haiku/tool.yaml
new file mode 100644
index 000000000..902eae889
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-haiku/tool.yaml
@@ -0,0 +1,61 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 468
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-haiku-20240307-v1%3A0/invoke
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 337
+ body: '{"id":"msg_bdrk_012EK8eom7ArLnbCQErFKxPY","type":"message","role":"assistant","model":"claude-3-haiku-20240307","content":[{"type":"tool_use","id":"toolu_bdrk_018RFU2HzCBzsTUssfjW6HQP","name":"weather","input":{"location":"Florence, Italy"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":345,"output_tokens":53}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.068856584s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 765
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"},{"content":[{"id":"toolu_bdrk_018RFU2HzCBzsTUssfjW6HQP","input":{"location":"Florence, Italy"},"name":"weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_bdrk_018RFU2HzCBzsTUssfjW6HQP","content":[{"text":"40 C","type":"text"}],"type":"tool_result"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-haiku-20240307-v1%3A0/invoke
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 284
+ body: '{"id":"msg_bdrk_0158zRRWfj852Wxa71rG33PN","type":"message","role":"assistant","model":"claude-3-haiku-20240307","content":[{"type":"text","text":"The weather in Florence, Italy is 40°C."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":413,"output_tokens":16}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.069127458s
diff --git a/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-haiku/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-haiku/tool_streaming.yaml
new file mode 100644
index 000000000..0839eabc7
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-haiku/tool_streaming.yaml
@@ -0,0 +1,166 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 468
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-haiku-20240307-v1%3A0/invoke-with-response-stream
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: !!binary |
+ AAAB3QAAAEs+FS88CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcG
+ xpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJs
+ SWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZl
+ ltUnlhMTh3TVRWYWIycHdPSFZDU2tOV2Mxb3lWVTFrVUhjNVZIa2lMQ0owZVhCbElqb2li
+ V1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWV
+ hWa1pTMHpMV2hoYVd0MUxUSXdNalF3TXpBM0lpd2lZMjl1ZEdWdWRDSTZXMTBzSW5OMGIz
+ QmZjbVZoYzI5dUlqcHVkV3hzTENKemRHOXdYM05sY1hWbGJtTmxJanB1ZFd4c0xDSjFjMk
+ ZuWlNJNmV5SnBibkIxZEY5MGIydGxibk1pT2pNME5Td2liM1YwY0hWMFgzUnZhMlZ1Y3lJ
+ Nk1YMTlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJIn
+ 2LKU8sAAABbAAAAEsTsg6YCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcA
+ EGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5Sj
+ BlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTl6ZEdGeWRDSXNJbWx1WkdWNElqb3dMQ0pq
+ YjI1MFpXNTBYMkpzYjJOcklqcDdJblI1Y0dVaU9pSjBiMjlzWDNWelpTSXNJbWxrSWpvaW
+ RHOXZiSFZmWW1SeWExOHdNVE5OY0RSSFVFaENkWGREUzBOblNFd3lZVVpTVWtRaUxDSnVZ
+ VzFsSWpvaWQyVmhkR2hsY2lJc0ltbHVjSFYwSWpwN2ZYMTkiLCJwIjoiYWJjZGVmZ2hpam
+ tsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NSJ97GfC
+ bAAAAQkAAABLQmD2pQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcH
+ BsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhC
+ bElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeD
+ BZU0k2ZXlKMGVYQmxJam9pYVc1d2RYUmZhbk52Ymw5a1pXeDBZU0lzSW5CaGNuUnBZV3hm
+ YW5OdmJpSTZJaUo5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekEifd
+ tArrsAAAEtAAAAS3Yhf2ELOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQ
+ YXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMG
+ VYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmta
+ V3gwWVNJNmV5SjBlWEJsSWpvaWFXNXdkWFJmYW5OdmJsOWtaV3gwWVNJc0luQmhjblJwWV
+ d4ZmFuTnZiaUk2SW50Y0lteHZZMkYwYVNKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5v
+ cHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZIn2Fq0KzAAABJgAAAEsB8U
+ 5wCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pz
+ b24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1
+ Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhC
+ bElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNkltOX
+ VYQ0k2SUNKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZH
+ SElKS0xNTk9QUVJTVFVWIn0r2XsOAAABJgAAAEsB8U5wCzpldmVudC10eXBlBwAFY2h1bm
+ sNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2
+ ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSX
+ NJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlr
+ Wld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNklsd2lSbXh2Y21VaWZYMD0iLCJwIjoiYW
+ JjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWIn0AG9ad
+ AAABIwAAAEvJEcEACzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcG
+ xpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJs
+ SWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MF
+ lTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZh
+ bk52YmlJNkltNWpaU3dnU1hSaGJIbGNJbjBpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm
+ 9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLIn3xhQpKAAAApgAAAEt7Sy1HCzpldmVudC10eXBl
+ BwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdH
+ lwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTl6
+ ZEc5d0lpd2lhVzVrWlhnaU9qQjkiLCJwIjoiYWJjZCJ99ip76AAAASUAAABLRlE0oAs6ZX
+ ZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTpt
+ ZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2liV1Z6YzJGblpWOW
+ taV3gwWVNJc0ltUmxiSFJoSWpwN0luTjBiM0JmY21WaGMyOXVJam9pZEc5dmJGOTFjMlVp
+ TENKemRHOXdYM05sY1hWbGJtTmxJanB1ZFd4c2ZTd2lkWE5oWjJVaU9uc2liM1YwY0hWMF
+ gzUnZhMlZ1Y3lJNk5UTjlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6
+ QUJDREVGR0hJIn3bFtXeAAABXgAAAEvIU+V+CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbn
+ RlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJi
+ eXRlcyI6ImV5SjBlWEJsSWpvaWJXVnpjMkZuWlY5emRHOXdJaXdpWVcxaGVtOXVMV0psWk
+ hKdlkyc3RhVzUyYjJOaGRHbHZiazFsZEhKcFkzTWlPbnNpYVc1d2RYUlViMnRsYmtOdmRX
+ NTBJam96TkRVc0ltOTFkSEIxZEZSdmEyVnVRMjkxYm5RaU9qTTFMQ0pwYm5adlkyRjBhVz
+ l1VEdGMFpXNWplU0k2T1RJekxDSm1hWEp6ZEVKNWRHVk1ZWFJsYm1ONUlqbzBPVEo5ZlE9
+ PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUoifRn9cj4=
+ headers:
+ Content-Type:
+ - application/vnd.amazon.eventstream
+ status: 200 OK
+ code: 200
+ duration: 645.980625ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 765
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"},{"content":[{"id":"toolu_bdrk_013Mp4GPHBuwCKCgHL2aFRRD","input":{"location":"Florence, Italy"},"name":"weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_bdrk_013Mp4GPHBuwCKCgHL2aFRRD","content":[{"text":"40 C","type":"text"}],"type":"tool_result"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-haiku-20240307-v1%3A0/invoke-with-response-stream
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: !!binary |
+ AAAB8QAAAEs6JO05CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcG
+ xpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJs
+ SWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZl
+ ltUnlhMTh3TVVzNE5WSm5aRUpMWkRGT1VHbHpWVmRXTm1aNmFUZ2lMQ0owZVhCbElqb2li
+ V1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWV
+ hWa1pTMHpMV2hoYVd0MUxUSXdNalF3TXpBM0lpd2lZMjl1ZEdWdWRDSTZXMTBzSW5OMGIz
+ QmZjbVZoYzI5dUlqcHVkV3hzTENKemRHOXdYM05sY1hWbGJtTmxJanB1ZFd4c0xDSjFjMk
+ ZuWlNJNmV5SnBibkIxZEY5MGIydGxibk1pT2pReE15d2liM1YwY0hWMFgzUnZhMlZ1Y3lJ
+ Nk5IMTlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSk
+ tMTU5PUFFSU1RVVldYWVowMTIifVzckXoAAAELAAAASzigpcULOmV2ZW50LXR5cGUHAAVj
+ aHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBw
+ AFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOXpkR0Z5
+ ZENJc0ltbHVaR1Y0SWpvd0xDSmpiMjUwWlc1MFgySnNiMk5ySWpwN0luUjVjR1VpT2lKMF
+ pYaDBJaXdpZEdWNGRDSTZJaUo5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2
+ d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlMifbFNJI4AAADwAAAAS8wYFywLOmV2ZW50LXR5cG
+ UHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10
+ eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOW
+ taV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlr
+ Wld4MFlTSXNJblJsZUhRaU9pSlVhR1VnZDJWaGRHaGxjaUJwYmlKOWZRPT0iLCJwIjoiYW
+ IifU661ToAAAEeAAAAS5CgvTcLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBl
+ BwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZX
+ lKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xD
+ SmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSWdSbX
+ h2Y21WdVkyVXNJRWwwWVd4NUlHbHpJRFF3SW4xOSIsInAiOiJhYmNkZWZnaGlqa2xtbm9w
+ cXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OIn0m+h/FAAAA9QAAAEsE+JhcCzpldmVudC10eX
+ BlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2Ut
+ dHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMT
+ lrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5
+ a1pXeDBZU0lzSW5SbGVIUWlPaUlnWkdWbmNtVmxjeUJEWld4emFYVnpMaUo5ZlE9PSIsIn
+ AiOiJhYmMifcY9TyoAAADKAAAASyeJtwsLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVu
+ dC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dG
+ VzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOXpkRzl3SWl3aWFXNWtaWGdp
+ T2pCOSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OIn
+ 1nPrWkAAABKwAAAEv5YYrBCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcA
+ EGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5Sj
+ BlWEJsSWpvaWJXVnpjMkZuWlY5a1pXeDBZU0lzSW1SbGJIUmhJanA3SW5OMGIzQmZjbVZo
+ YzI5dUlqb2laVzVrWDNSMWNtNGlMQ0p6ZEc5d1gzTmxjWFZsYm1ObElqcHVkV3hzZlN3aW
+ RYTmhaMlVpT25zaWIzVjBjSFYwWDNSdmEyVnVjeUk2TVRoOWZRPT0iLCJwIjoiYWJjZGVm
+ Z2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk8ifXy/aY0AAAFeAAAAS8hT5X
+ 4LOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNv
+ bg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pYldWemMyRm
+ 5aVjl6ZEc5d0lpd2lZVzFoZW05dUxXSmxaSEp2WTJzdGFXNTJiMk5oZEdsdmJrMWxkSEpw
+ WTNNaU9uc2lhVzV3ZFhSVWIydGxia052ZFc1MElqbzBNVE1zSW05MWRIQjFkRlJ2YTJWdV
+ EyOTFiblFpT2pFNExDSnBiblp2WTJGMGFXOXVUR0YwWlc1amVTSTZOalF3TENKbWFYSnpk
+ RUo1ZEdWTVlYUmxibU41SWpvME56QjlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3Bxcn
+ N0dXZ3eHl6QUJDREVGR0hJSiJ9pKyp0g==
+ headers:
+ Content-Type:
+ - application/vnd.amazon.eventstream
+ status: 200 OK
+ code: 200
+ duration: 626.53225ms
diff --git a/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-opus/simple.yaml b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-opus/simple.yaml
new file mode 100644
index 000000000..573a042d0
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-opus/simple.yaml
@@ -0,0 +1,32 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 211
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Say hi in Portuguese","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-opus-20240229-v1%3A0/invoke
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 246
+ body: '{"id":"msg_bdrk_01RtkNhyFaV3SeKS3ZTEJ5Sx","type":"message","role":"assistant","model":"claude-3-opus-20240229","content":[{"type":"text","text":"OlĆ”!"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":16,"output_tokens":7}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.276099s
diff --git a/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-opus/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-opus/simple_streaming.yaml
new file mode 100644
index 000000000..a0f192f31
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-opus/simple_streaming.yaml
@@ -0,0 +1,67 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 211
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Say hi in Portuguese","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-opus-20240229-v1%3A0/invoke-with-response-stream
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: !!binary |
+ AAAB5AAAAEuSJPXLCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcG
+ xpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJs
+ SWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZl
+ ltUnlhMTh3TVZaVFUwRm1NWEUwVG5WdFMyMDRSRkp5Wm5KQ1NGQWlMQ0owZVhCbElqb2li
+ V1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWV
+ hWa1pTMHpMVzl3ZFhNdE1qQXlOREF5TWpraUxDSmpiMjUwWlc1MElqcGJYU3dpYzNSdmNG
+ OXlaV0Z6YjI0aU9tNTFiR3dzSW5OMGIzQmZjMlZ4ZFdWdVkyVWlPbTUxYkd3c0luVnpZV2
+ RsSWpwN0ltbHVjSFYwWDNSdmEyVnVjeUk2TVRZc0ltOTFkSEIxZEY5MGIydGxibk1pT2pS
+ OWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk
+ 9QUVJTVCJ9nCryKgAAAQoAAABLBcCMdQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50
+ LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZX
+ MiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5emRHRnlkQ0lzSW1sdVpHVjRJ
+ am93TENKamIyNTBaVzUwWDJKc2IyTnJJanA3SW5SNWNHVWlPaUowWlhoMElpd2lkR1Y0ZE
+ NJNklpSjlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJ
+ SktMTU5PUFFSIn1f3S6rAAAA6AAAAEuciMtvCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbn
+ RlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJi
+ eXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1Wk
+ dWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVI
+ UWlPaUpQYk1PaElTSjlmUT09IiwicCI6ImFiY2RlZiJ9Sl5pmgAAAM0AAABLlalrGws6ZX
+ ZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTpt
+ ZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOW
+ liRzlqYTE5emRHOXdJaXdpYVc1a1pYZ2lPakI5IiwicCI6ImFiY2RlZmdoaWprbG1ub3Bx
+ cnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFEifWCrdTQAAAErAAAAS/lhisELOmV2ZW50LX
+ R5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2Fn
+ ZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pYldWemMyRm5aVjlrWld4MF
+ lTSXNJbVJsYkhSaElqcDdJbk4wYjNCZmNtVmhjMjl1SWpvaVpXNWtYM1IxY200aUxDSnpk
+ Rzl3WDNObGNYVmxibU5sSWpwdWRXeHNmU3dpZFhOaFoyVWlPbnNpYjNWMGNIVjBYM1J2YT
+ JWdWN5STZOMzE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJ
+ SktMTU5PUFFSUyJ944scGQAAATsAAABLmYEdQws6ZXZlbnQtdHlwZQcABWNodW5rDTpjb2
+ 50ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsi
+ Ynl0ZXMiOiJleUowZVhCbElqb2liV1Z6YzJGblpWOXpkRzl3SWl3aVlXMWhlbTl1TFdKbF
+ pISnZZMnN0YVc1MmIyTmhkR2x2YmsxbGRISnBZM01pT25zaWFXNXdkWFJVYjJ0bGJrTnZk
+ VzUwSWpveE5pd2liM1YwY0hWMFZHOXJaVzVEYjNWdWRDSTZOeXdpYVc1MmIyTmhkR2x2Ym
+ t4aGRHVnVZM2tpT2pFd01qZ3NJbVpwY25OMFFubDBaVXhoZEdWdVkza2lPamt6TUgxOSIs
+ InAiOiJhYmNkZSJ9RFHKLg==
+ headers:
+ Content-Type:
+ - application/vnd.amazon.eventstream
+ status: 200 OK
+ code: 200
+ duration: 1.078504542s
diff --git a/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-opus/tool.yaml b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-opus/tool.yaml
new file mode 100644
index 000000000..d12fa4ec2
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-opus/tool.yaml
@@ -0,0 +1,61 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 468
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-opus-20240229-v1%3A0/invoke
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 815
+ body: '{"id":"msg_bdrk_01CEbaoBED7NgBWRnBAajncY","type":"message","role":"assistant","model":"claude-3-opus-20240229","content":[{"type":"text","text":"\nThe weather tool is relevant for answering this request, as the user is asking for weather information for a specific location.\n\nThe weather tool requires one parameter:\n- location (string): This is provided directly by the user as \"Florence, Italy\"\n\nSince the required location parameter is present, we can proceed with calling the weather tool to get the current weather for Florence, Italy. No other tools are needed.\n"},{"type":"tool_use","id":"toolu_bdrk_011Dt2H7KtvCCYp7J4peboKa","name":"weather","input":{"location":"Florence, Italy"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":614,"output_tokens":143}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 7.551935583s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1263
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"},{"content":[{"text":"\u003cthinking\u003e\nThe weather tool is relevant for answering this request, as the user is asking for weather information for a specific location.\n\nThe weather tool requires one parameter:\n- location (string): This is provided directly by the user as \"Florence, Italy\"\n\nSince the required location parameter is present, we can proceed with calling the weather tool to get the current weather for Florence, Italy. No other tools are needed.\n\u003c/thinking\u003e","type":"text"},{"id":"toolu_bdrk_011Dt2H7KtvCCYp7J4peboKa","input":{"location":"Florence, Italy"},"name":"weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_bdrk_011Dt2H7KtvCCYp7J4peboKa","content":[{"text":"40 C","type":"text"}],"type":"tool_result"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-opus-20240229-v1%3A0/invoke
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 716
+ body: '{"id":"msg_bdrk_01MqUoomGzEKtaeBmJgxooMM","type":"message","role":"assistant","model":"claude-3-opus-20240229","content":[{"type":"text","text":"With a temperature of 40°C (104°F), Florence is currently experiencing very hot weather and a heatwave. To summarize:\n- The current temperature in Florence, Italy is 40°C (104°F) \n- This is considered very hot and indicates a heatwave is occurring\n\nIf you will be in Florence, be sure to stay hydrated, avoid strenuous outdoor activity during the hottest parts of the day, and seek out air conditioning when possible. Let me know if you need any other information!"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":771,"output_tokens":117}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 6.374604291s
diff --git a/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-opus/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-opus/tool_streaming.yaml
new file mode 100644
index 000000000..e42c81474
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-opus/tool_streaming.yaml
@@ -0,0 +1,507 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 468
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-opus-20240229-v1%3A0/invoke-with-response-stream
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: !!binary |
+ AAAB8wAAAEtA5L5ZCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcG
+ xpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJs
+ SWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZl
+ ltUnlhMTh3TVRneldtOW5RV2xpVldkaWRVTnBUR2hhTW5remRqWWlMQ0owZVhCbElqb2li
+ V1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWV
+ hWa1pTMHpMVzl3ZFhNdE1qQXlOREF5TWpraUxDSmpiMjUwWlc1MElqcGJYU3dpYzNSdmNG
+ OXlaV0Z6YjI0aU9tNTFiR3dzSW5OMGIzQmZjMlZ4ZFdWdVkyVWlPbTUxYkd3c0luVnpZV2
+ RsSWpwN0ltbHVjSFYwWDNSdmEyVnVjeUk2TmpFMExDSnZkWFJ3ZFhSZmRHOXJaVzV6SWpv
+ MWZYMTkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk
+ 9QUVJTVFVWV1hZWjAxMjM0NTY3OCJ9IfUzWgAAAOgAAABLnIjLbws6ZXZlbnQtdHlwZQcA
+ BWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cG
+ UHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5emRH
+ RnlkQ0lzSW1sdVpHVjRJam93TENKamIyNTBaVzUwWDJKc2IyTnJJanA3SW5SNWNHVWlPaU
+ owWlhoMElpd2lkR1Y0ZENJNklpSjlmUT09IiwicCI6ImFiY2RlZmdoaWoifZlWRnsAAAEd
+ AAAAS9cAx+cLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYX
+ Rpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9p
+ WTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNm
+ V5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSThkR2hwYm10cGJtYytY
+ RzVVYnlCblpYUWdkR2hsSUhkbFlYUm9aWElpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm
+ 9wcXJzdHV2d3h5ekEifY6sG7YAAAETAAAAS2gweYYLOmV2ZW50LXR5cGUHAAVjaHVuaw06
+ Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbn
+ R7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0lt
+ bHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJbl
+ JsZUhRaU9pSWdabTl5WldOaGMzUWlmWDA9IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0
+ dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSUyJ9WBzdsgAAARAAAABLL5ADVgs6ZXZlbnQtdH
+ lwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdl
+ LXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYT
+ E5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRG
+ OWtaV3gwWVNJc0luUmxlSFFpT2lJZ1ptOXlJRVpzYjNKbGJtTmxMQ0JKZEdGc2VTd2lmWD
+ A9IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6In2OVPAEAAAA/QAAAEs0iNOd
+ CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb2
+ 4NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1
+ ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbE
+ lqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUlnU1NCM2IzVnNaQ0J1WldWa0lIUnZJ
+ SFZ6WlNKOWZRPT0iLCJwIjoiYWJjZGVmZyJ94AtzbQAAAPwAAABLCej6LQs6ZXZlbnQtdH
+ lwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdl
+ LXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYT
+ E5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRG
+ OWtaV3gwWVNJc0luUmxlSFFpT2lJZ2RHaGxJbjE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3
+ BxcnN0dXZ3eHl6QUJDRCJ98NPfjAAAARQAAABL2hCllgs6ZXZlbnQtdHlwZQcABWNodW5r
+ DTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldm
+ VudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lz
+ SW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0
+ luUmxlSFFpT2lJZ1hDSWlmWDA9IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6
+ QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMSJ9/sxxyAAAARMAAABLaDB5hgs6ZXZlbn
+ QtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNz
+ YWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRz
+ lqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdW
+ NGRGOWtaV3gwWVNJc0luUmxlSFFpT2lKM1pXRjBhR1Z5WENJZ2RHOXZiQzRnVEdWMEluMT
+ kiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHIn3lHBMgAAABAwAA
+ AEsI0O4ECzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW
+ 9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVky
+ OXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleU
+ owZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUluY3lCamFHVmpheUo5ZlE9
+ PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQyJ9qyAQagAAAOYAAABLI7
+ h1Dgs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9q
+ c29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZE
+ dWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVY
+ QmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ2FXWWlmWDA9IiwicCI6ImFiY2
+ RlZmdoIn1qzDL1AAABEQAAAEsS8CrmCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQt
+ dHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcy
+ I6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElq
+ b3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaU
+ lnU1NKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElK
+ S0xNTk9QUVJTVFVWV1hZIn3fIIuTAAABBwAAAEv9UEjECzpldmVudC10eXBlBwAFY2h1bm
+ sNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2
+ ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSX
+ NJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lz
+ SW5SbGVIUWlPaUlnYUdGMlpTQjBhR1VnY21WeGRXbHlaU0o5ZlE9PSIsInAiOiJhYmNkZW
+ ZnaGlqa2xtbm9wcXJzdHUifVQwPzwAAAEVAAAAS+dwjCYLOmV2ZW50LXR5cGUHAAVjaHVu
+ aw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZX
+ ZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJ
+ c0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSX
+ NJblJsZUhRaU9pSmtJSEJoY21GdFpYUmxjbk02SW4xOSIsInAiOiJhYmNkZWZnaGlqa2xt
+ bm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRIn3ITNvcAAAA/gAAAEtzKKlNCzpldm
+ VudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1l
+ c3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aW
+ JHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lk
+ R1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUpjYmx4dVVtVnhkV2x5WlNKOWZRPT0iLCJwIj
+ oiYWJjZGVmZ2hpamtsbW5vcHFyc3QifZqqisoAAAE0AAAASxvRipILOmV2ZW50LXR5cGUH
+ AAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eX
+ BlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWta
+ V3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWl
+ d4MFlTSXNJblJsZUhRaU9pSmtJSEJoY21GdFpYUmxjbk02WEc0dElHeHZZMkYwYVc5dUlu
+ MTkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUV
+ JTVFVWV1hZWjAxMjM0NSJ9X128vwAAAOoAAABL5kiYDws6ZXZlbnQtdHlwZQcABWNodW5r
+ DTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldm
+ VudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lz
+ SW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0
+ luUmxlSFFpT2lJNklGUm9aU0o5ZlE9PSIsInAiOiJhYmNkZWZnaCJ9obCe0gAAAP0AAABL
+ NIjTnQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi
+ 9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1
+ ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMG
+ VYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ2RYTmxjaUo5ZlE9PSIsInAi
+ OiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekEifaflFXoAAAEcAAAAS+pg7lcLOmV2ZW
+ 50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVz
+ c2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYk
+ c5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRH
+ VjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSWdjSEp2ZG1sa1pXUWdYQ0lpZlgwPSIsInAiOi
+ JhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWCJ9
+ 7KCwRwAAAQgAAABLfwDfFQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHAB
+ BhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUow
+ ZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1
+ pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lKR2JHOXla
+ VzVqWlN3aWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSC
+ J9SSVSKgAAAQUAAABLh5AbpAs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUH
+ ABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleU
+ owZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENK
+ a1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lKSmRHRn
+ NlVndpTENKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERSJ9
+ Q7h/jwAAARQAAABL2hCllgs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHAB
+ BhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUow
+ ZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1
+ pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ2MyOGdk
+ R2hwY3lCcGN5QmhkbUZwYkdGaWJHVWlmWDA9IiwicCI6ImFiY2RlZmdoaWprbG1ub3Bxcn
+ N0dXZ3eHl6QUJDRCJ93a0EPQAAAQMAAABLCNDuBAs6ZXZlbnQtdHlwZQcABWNodW5rDTpj
+ b250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudH
+ siYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1s
+ dVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUm
+ xlSFFpT2lJdUluMTkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZH
+ SElKS0xNTk8ifRgO5sEAAAEFAAAAS4eQG6QLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udG
+ VudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5
+ dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1
+ Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhR
+ aU9pSmNibHh1UVd4c0luMTkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQk
+ NERUZHSEkife/I5eEAAAETAAAAS2gweYYLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVu
+ dC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dG
+ VzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0
+ SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU
+ 9pSWdjbVZ4ZFdseVpTSjlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6
+ QUJDREVGR0hJSktMTU5PUFFSUyJ9cQFVNgAAAQgAAABLfwDfFQs6ZXZlbnQtdHlwZQcABW
+ NodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUH
+ AAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeD
+ BZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gw
+ WVNJc0luUmxlSFFpT2lKa0lIQmhjbUZ0WlhSbGNuTWdZWEpsSUhCeWIzWnBaR1VpZlgwPS
+ IsInAiOiJhYmNkZWZnaGlqa2xtbiJ9TrYinQAAAPsAAABLu8gmPQs6ZXZlbnQtdHlwZQcA
+ BWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cG
+ UHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pX
+ eDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3
+ gwWVNJc0luUmxlSFFpT2lKa0xDQnpieUJKSUdOaGJpQndjbTlqWldVaWZYMD0iLCJwIjoi
+ YWJjZGVmZ2hpIn0It+lcAAABBQAAAEuHkBukCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbn
+ RlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJi
+ eXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1Wk
+ dWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVI
+ UWlPaUprSUhkcGRHZ2dZMkZzYkdsdVp5QjBhR1VnZDJWaGRHaGxjaUo5ZlE9PSIsInAiOi
+ JhYmNkZWZnIn2zw73gAAAA6QAAAEuh6OLfCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRl
+ bnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieX
+ RlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdW
+ NElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUW
+ lPaUlnZEc5dmJDNGlmWDA9IiwicCI6ImFiY2RlZmcifR6NDHcAAAEgAAAAS46xu9ALOmV2
+ ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bW
+ Vzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlp
+ Ykc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaW
+ RHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSmNiand2ZEdocGJtdHBibWMrSW4xOSIsInAi
+ OiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWF
+ laMDEifV5oYGAAAACtAAAASwybHFYLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10
+ eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIj
+ oiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOXpkRzl3SWl3aWFXNWtaWGdpT2pC
+ OSIsInAiOiJhYmNkZWZnaGlqayJ9Eti/pwAAATUAAABLJrGjIgs6ZXZlbnQtdHlwZQcABW
+ NodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUH
+ AAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5emRHRn
+ lkQ0lzSW1sdVpHVjRJam94TENKamIyNTBaVzUwWDJKc2IyTnJJanA3SW5SNWNHVWlPaUow
+ YjI5c1gzVnpaU0lzSW1sa0lqb2lkRzl2YkhWZlltUnlhMTh3TVV4aVdFZzBWV2xFU0VGeU
+ 0xb3hSWFEyVG5oMmR6UWlMQ0p1WVcxbElqb2lkMlZoZEdobGNpSXNJbWx1Y0hWMElqcDdm
+ WDE5IiwicCI6ImFiYyJ9/8QMWgAAAPQAAABLOZix7As6ZXZlbnQtdHlwZQcABWNodW5rDT
+ pjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVu
+ dHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW
+ 1sdVpHVjRJam94TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pYVc1d2RYUmZhbk52Ymw5a1pX
+ eDBZU0lzSW5CaGNuUnBZV3hmYW5OdmJpSTZJaUo5ZlE9PSIsInAiOiJhYmNkZWYifen1Ho
+ MAAAEJAAAAS0Jg9qULOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBw
+ bGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQm
+ xJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpveExDSmtaV3gw
+ WVNJNmV5SjBlWEJsSWpvaWFXNXdkWFJmYW5OdmJsOWtaV3gwWVNJc0luQmhjblJwWVd4Zm
+ FuTnZiaUk2SW50Y0lteHZZeUo5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzIn3i
+ PxRNAAABLAAAAEtLQVbRCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEG
+ FwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBl
+ WEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWl
+ d4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlX
+ eGZhbk52YmlJNkltRjBhVzl1WENJaWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3
+ R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxIn34jJ/+AAABIgAAAEv0ceiw
+ CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb2
+ 4NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1
+ ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUowZVhCbE
+ lqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNklqb2dY
+ Q0lpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE
+ 1OT1BRUlNUVVYifa8NN6wAAAEkAAAAS3sxHRALOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29u
+ dGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7Im
+ J5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVa
+ R1Y0SWpveExDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWFXNXdkWFJmYW5OdmJsOWtaV3gwWV
+ NJc0luQmhjblJwWVd4ZmFuTnZiaUk2SWtac2IzSmxibU5sTENKOWZRPT0iLCJwIjoiYWJj
+ ZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QIn1JQtToAAABAQAAAE
+ tyEL1kCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9u
+ L2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOX
+ VkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUow
+ ZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNk
+ lrbDBZU0o5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm8ifRwiiHUAAAEhAAAAS7PRkmAL
+ OmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg
+ 06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVk
+ RjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpveExDSmtaV3gwWVNJNmV5SjBlWEJsSW
+ pvaWFXNXdkWFJmYW5OdmJsOWtaV3gwWVNJc0luQmhjblJwWVd4ZmFuTnZiaUk2SW14NVhD
+ SjlJbjE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU
+ 5PUFFSU1RVIn1ATzw7AAAA1AAAAEv4WZ7oCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRl
+ bnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieX
+ RlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTl6ZEc5d0lpd2lhVzVrWlhn
+ aU9qRjkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk
+ 9QUVJTVFVWV1gifYm3LbgAAAEXAAAAS52w30YLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29u
+ dGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7Im
+ J5dGVzIjoiZXlKMGVYQmxJam9pYldWemMyRm5aVjlrWld4MFlTSXNJbVJsYkhSaElqcDdJ
+ bk4wYjNCZmNtVmhjMjl1SWpvaWRHOXZiRjkxYzJVaUxDSnpkRzl3WDNObGNYVmxibU5sSW
+ pwdWRXeHNmU3dpZFhOaFoyVWlPbnNpYjNWMGNIVjBYM1J2YTJWdWN5STZNVEk0ZlgwPSIs
+ InAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHUiffW4C7AAAAF6AAAAS/wSbLoLOmV2ZW50LX
+ R5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2Fn
+ ZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pYldWemMyRm5aVjl6ZEc5d0
+ lpd2lZVzFoZW05dUxXSmxaSEp2WTJzdGFXNTJiMk5oZEdsdmJrMWxkSEpwWTNNaU9uc2lh
+ VzV3ZFhSVWIydGxia052ZFc1MElqbzJNVFFzSW05MWRIQjFkRlJ2YTJWdVEyOTFiblFpT2
+ pFeE15d2lhVzUyYjJOaGRHbHZia3hoZEdWdVkza2lPalV6TURJc0ltWnBjbk4wUW5sMFpV
+ eGhkR1Z1WTNraU9qRXhNeko5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3
+ h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyMzQ1NjcifWtlLt8=
+ headers:
+ Content-Type:
+ - application/vnd.amazon.eventstream
+ status: 200 OK
+ code: 200
+ duration: 1.626768792s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1158
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"},{"content":[{"text":"\u003cthinking\u003e\nTo get the weather forecast for Florence, Italy, I would need to use the \"weather\" tool. Let''s check if I have the required parameters:\n\nRequired parameters:\n- location: The user provided \"Florence,Italy\", so this is available.\n\nAll required parameters are provided, so I can proceed with calling the weather tool.\n\u003c/thinking\u003e","type":"text"},{"id":"toolu_bdrk_01LbXH4UiDHAr3Z1Et6Nxvw4","input":{"location":"Florence,Italy"},"name":"weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_bdrk_01LbXH4UiDHAr3Z1Et6Nxvw4","content":[{"text":"40 C","type":"text"}],"type":"tool_result"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-opus-20240229-v1%3A0/invoke-with-response-stream
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: !!binary |
+ AAAB2gAAAEuMNfMsCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcG
+ xpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJs
+ SWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZl
+ ltUnlhMTh3TVVOVWFGaDZaSFJ0UjFKVk1XZDJkR3BhY1VWSVZ6Z2lMQ0owZVhCbElqb2li
+ V1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWV
+ hWa1pTMHpMVzl3ZFhNdE1qQXlOREF5TWpraUxDSmpiMjUwWlc1MElqcGJYU3dpYzNSdmNG
+ OXlaV0Z6YjI0aU9tNTFiR3dzSW5OMGIzQmZjMlZ4ZFdWdVkyVWlPbTUxYkd3c0luVnpZV2
+ RsSWpwN0ltbHVjSFYwWDNSdmEyVnVjeUk2TnpVMkxDSnZkWFJ3ZFhSZmRHOXJaVzV6SWpv
+ eWZYMTkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKIn2eBB
+ J4AAAA5wAAAEse2Fy+CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFw
+ cGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWE
+ JsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTl6ZEdGeWRDSXNJbWx1WkdWNElqb3dMQ0pqYjI1
+ MFpXNTBYMkpzYjJOcklqcDdJblI1Y0dVaU9pSjBaWGgwSWl3aWRHVjRkQ0k2SWlKOWZRPT
+ 0iLCJwIjoiYWJjZGVmZ2hpIn20w8gnAAABCgAAAEsFwIx1CzpldmVudC10eXBlBwAFY2h1
+ bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABW
+ V2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlT
+ SXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0
+ lzSW5SbGVIUWlPaUpjYmx4dVFXTmpiM0prYVc1bkluMTkiLCJwIjoiYWJjZGVmZ2hpamts
+ bW5vcHFyc3R1dnd4eXpBQkNERUYifYw9rFkAAAETAAAAS2gweYYLOmV2ZW50LXR5cGUHAA
+ VjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBl
+ BwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3
+ gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4
+ MFlTSXNJblJsZUhRaU9pSWdkRzhnZEdobElIZGxZWFJvWlhJZ2FXNW1iM0p0WVhScGIyNG
+ lmWDA9IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dSJ9pKcRmQAAAPoAAABLhqgPjQs6
+ ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDT
+ ptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRG
+ OWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam
+ 9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJc0luMTkiLCJwIjoiYWJjZGVmZ2hpamts
+ bW5vcHFyc3R1dnd4eXpBQkNERUYifRaFvcMAAAEMAAAAS4qAedULOmV2ZW50LXR5cGUHAA
+ VjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBl
+ BwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3
+ gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4
+ MFlTSXNJblJsZUhRaU9pSWdkR2hsSUdOMWNuSmxiblFnZDJWaGRHaGxjaUJwYmlCR2JHOX
+ laVzVqWlNKOWZRPT0iLCJwIjoiYWJjZGVmIn0Zooh4AAAA7QAAAEtUaEQfCzpldmVudC10
+ eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2
+ UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWph
+ MTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZE
+ Y5a1pXeDBZU0lzSW5SbGVIUWlPaUlzSUVsMFlXeDVJR2x6SURRd0luMTkiLCJwIjoiYWJj
+ In1lkmmLAAABFgAAAEug0Pb2CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQ
+ cAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5
+ SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0
+ prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUlnWkdW
+ bmNtVmxjeUJEWld4emFYVnpMaUo5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdH
+ V2d3h5ekFCQ0RFRkdISUoifYRLIlcAAAEUAAAAS9oQpZYLOmV2ZW50LXR5cGUHAAVjaHVu
+ aw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZX
+ ZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJ
+ c0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSX
+ NJblJsZUhRaU9pSWdOREFpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5
+ ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEifcrhPoQAAAEHAAAAS/1QSMQLOmV2ZW
+ 50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVz
+ c2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYk
+ c5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRH
+ VjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSWdReUo5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2
+ xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OTyJ9W//SfAAAAOkAAABLoeji3ws6ZXZl
+ bnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZX
+ NzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWli
+ RzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZE
+ dWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ2FYTWdkbVZ5ZVNKOWZRPT0iLCJwIjoiYWJj
+ In24tBuaAAAA7AAAAEtpCG2vCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQ
+ cAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5
+ SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0
+ prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUlnYUc5
+ MExDQnpieUJwWmlKOWZRPT0iLCJwIjoiYWIifZkzXbsAAAEDAAAASwjQ7gQLOmV2ZW50LX
+ R5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2Fn
+ ZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5am
+ ExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRk
+ RjlrWld4MFlTSXNJblJsZUhRaU9pSWdlVzkxSUdGeVpTSjlmUT09IiwicCI6ImFiY2RlZm
+ doaWprbG1ub3BxcnN0dXZ3eHl6QUJDIn22/KwfAAAA8gAAAEu22ERMCzpldmVudC10eXBl
+ BwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdH
+ lwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlr
+ Wld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1
+ pXeDBZU0lzSW5SbGVIUWlPaUlnYVc0aWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFy
+ c3QifX/DWjEAAADsAAAAS2kIba8LOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eX
+ BlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoi
+ ZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0
+ xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSWdS
+ bXh2Y21WdVkyVWdZbVVpZlgwPSIsInAiOiJhYiJ98uF2AAAAAQcAAABL/VBIxAs6ZXZlbn
+ QtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNz
+ YWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRz
+ lqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdW
+ NGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ2MzVnlaU0o5ZlE9PSIsInAiOiJhYmNkZWZnaG
+ lqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLIn1Y8Xx5AAAA9wAAAEt+OMs8CzpldmVu
+ dC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3
+ NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJH
+ OWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1
+ Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUlnZEc4Z2MzUmhlU0o5ZlE9PSIsInAiOiJhYmNk
+ ZWZnaGlqa2xtbm9wcSJ9snZtbgAAARoAAABLZSAb9ws6ZXZlbnQtdHlwZQcABWNodW5rDT
+ pjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVu
+ dHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW
+ 1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0lu
+ UmxlSFFpT2lJZ2FIbGtjbUYwWldRc0luMTkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3
+ R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWiJ9aon3zgAAAQMAAABLCNDuBAs6
+ ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDT
+ ptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRG
+ OWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam
+ 9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ2QyVmhjaUJzYVdkb2RDSjlmUT09Iiwi
+ cCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHkifVtLl6kAAAEMAAAAS4qAedULOmV2ZW
+ 50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVz
+ c2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYk
+ c5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRH
+ VjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSXNJR0p5WldGMGFHRmliR1VnWTJ4dmRHaHBibW
+ NzSW4xOSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2In3tqmFbAAABHAAAAEvqYO5X
+ CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb2
+ 4NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1
+ ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbE
+ lqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUlnWVc1a0lHRjJiMmxrSUdKbGFXNW5J
+ bjE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUF
+ FSU1QifSSwZ1YAAAE7AAAAS5mBHUMLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10
+ eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIj
+ oiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpv
+ d0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSW
+ dhVzRnWkdseVpXTjBJSE4xYm14cFoyaDBJR1IxY21sdVp5SjlmUT09IiwicCI6ImFiY2Rl
+ ZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzND
+ U2NzgifZNM/zAAAAEHAAAAS/1QSMQLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10
+ eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIj
+ oiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpv
+ d0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSW
+ dkR2hsSUdodmRIUmxjM1FnY0dGeWRITWdiMllpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xt
+ bm9wcSJ9o+NC1wAAARkAAABLIoBhJws6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LX
+ R5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMi
+ OiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam
+ 93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJ
+ Z2RHaGxJR1JoZVNCcFppSjlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eH
+ l6QUJDREVGR0hJSktMTU5PUFFSU1RVIn0XTZnCAAAA+QAAAEvBCHVdCzpldmVudC10eXBl
+ BwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdH
+ lwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlr
+ Wld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1
+ pXeDBZU0lzSW5SbGVIUWlPaUlnY0c5emMybGliR1V1SUVraWZYMD0iLCJwIjoiYWJjZGVm
+ Z2hpamtsbW5vIn0jx543AAAA8QAAAEvxeD6cCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbn
+ RlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJi
+ eXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1Wk
+ dWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVI
+ UWlPaUluSW4xOSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2dyJ9y4vCRwAAAUAAAA
+ BLF4PMnQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlv
+ bi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMj
+ l1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlK
+ MGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lKa0lISmxZMjl0YldWdVpDQm
+ phR1ZqYTJsdVp5QjBhR1VnWlhoMFpXNWtaU0o5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xt
+ bm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyMzQ1In2fv5/BAA
+ AA9wAAAEt+OMs8CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxp
+ Y2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSW
+ pvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlT
+ STZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUprSUdadmNtVmpZWE
+ 4wSUdGekluMTkiLCJwIjoiYWJjZGVmZ2hpamtsbSJ9kYo3sAAAAScAAABLPJFnwAs6ZXZl
+ bnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZX
+ NzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWli
+ RzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZE
+ dWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ2QyVnNiQ0IwYnlCelpXVWlmWDA9IiwicCI6
+ ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWV
+ owMTIzNDU2NzgifUJUr+UAAADpAAAAS6Ho4t8LOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29u
+ dGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7Im
+ J5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVa
+ R1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZU
+ hRaU9pSWdhRzkzSW4xOSIsInAiOiJhYmNkZWZnaGlqayJ9GNiSKwAAAQUAAABLh5AbpAs6
+ ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDT
+ ptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRG
+ OWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam
+ 9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ2JHOXVaeUo5ZlE9PSIsInAiOiJhYmNk
+ ZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISSJ9EORPygAAAPkAAABLwQh1XQs6ZX
+ ZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTpt
+ ZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOW
+ liRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9p
+ ZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ2RHaHBjeUo5ZlE9PSIsInAiOiJhYmNkZW
+ ZnaGlqa2xtbm9wcXJzdHV2dyJ9iTig+gAAAR4AAABLkKC9Nws6ZXZlbnQtdHlwZQcABWNo
+ dW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAA
+ VldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZ
+ U0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWV
+ NJc0luUmxlSFFpT2lJZ2FHVmhkQ0o5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJz
+ dHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyMzQ1NjcifSU+eNkAAAEcAA
+ AAS+pg7lcLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRp
+ b24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWT
+ I5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5
+ SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSWdkMkYyWlNCdFlYa2diR0
+ Z6ZEM0aWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElK
+ S0xNTk9QUVJTVCJ9sLQdbQAAAQcAAABL/VBIxAs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb2
+ 50ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsi
+ Ynl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdV
+ pHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxl
+ SFFpT2lKY2JseHVUR1YwSW4xOSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ek
+ FCQ0RFRkdISUpLIn2dJjGZAAABFwAAAEudsN9GCzpldmVudC10eXBlBwAFY2h1bmsNOmNv
+ bnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50ey
+ JieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1
+ WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbG
+ VIUWlPaUlnYldVZ2EyNXZkeUJwWmlCNWIzVWdibVZsSW4xOSIsInAiOiJhYmNkZWZnaGlq
+ a2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLIn2bxHVwAAABKgAAAEvEAaNxCzpldmVudC
+ 10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3Nh
+ Z2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOW
+ phMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0
+ ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUprSUdGdWVTQnZkR2hsY2lCcGJtWnZjbTFoZEdsdm
+ JpSjlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktM
+ TU5PUFFSU1RVViJ9E1MeGgAAAQsAAABLOKClxQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb2
+ 50ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsi
+ Ynl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdV
+ pHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxl
+ SFFpT2lJZ1lXSnZkWFFpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ek
+ FCQ0RFRkdISUpLTE1OTyJ9aoJBTAAAAQUAAABLh5AbpAs6ZXZlbnQtdHlwZQcABWNodW5r
+ DTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldm
+ VudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lz
+ SW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0
+ luUmxlSFFpT2lJZ2RHaGxJSGRsWVhSb1pYSWdhVzRnUm14dmNtVnVZMlVnYjNJaWZYMD0i
+ LCJwIjoiYWJjZGVmZyJ96tazKQAAAPUAAABLBPiYXAs6ZXZlbnQtdHlwZQcABWNodW5rDT
+ pjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVu
+ dHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW
+ 1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0lu
+ UmxlSFFpT2lJZ2RISmhkbVZzYVc1bkluMTkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vIn2z7l
+ 3wAAAA/QAAAEs0iNOdCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFw
+ cGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWE
+ JsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4
+ MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUlnZEdobGNtVW
+ hJbjE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QSJ93ckogQAAAN8AAABL
+ j4mv+Qs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi
+ 9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1
+ ZEdWdWRGOWliRzlqYTE5emRHOXdJaXdpYVc1a1pYZ2lPakI5IiwicCI6ImFiY2RlZmdoaW
+ prbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2Nzgi
+ fd94LWgAAAE4AAAAS94hZ5MLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBw
+ AQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlK
+ MGVYQmxJam9pYldWemMyRm5aVjlrWld4MFlTSXNJbVJsYkhSaElqcDdJbk4wYjNCZmNtVm
+ hjMjl1SWpvaVpXNWtYM1IxY200aUxDSnpkRzl3WDNObGNYVmxibU5sSWpwdWRXeHNmU3dp
+ ZFhOaFoyVWlPbnNpYjNWMGNIVjBYM1J2YTJWdWN5STZNVEE1ZlgwPSIsInAiOiJhYmNkZW
+ ZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEiffyY
+ BjgAAAF1AAAAS35C+2sLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYX
+ BwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVY
+ QmxJam9pYldWemMyRm5aVjl6ZEc5d0lpd2lZVzFoZW05dUxXSmxaSEp2WTJzdGFXNTJiMk
+ 5oZEdsdmJrMWxkSEpwWTNNaU9uc2lhVzV3ZFhSVWIydGxia052ZFc1MElqbzNOVFlzSW05
+ MWRIQjFkRlJ2YTJWdVEyOTFiblFpT2pFd09Td2lhVzUyYjJOaGRHbHZia3hoZEdWdVkza2
+ lPalU0T1Rnc0ltWnBjbk4wUW5sMFpVeGhkR1Z1WTNraU9qRTFPRGg5ZlE9PSIsInAiOiJh
+ YmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMD
+ EyIn36LvYd
+ headers:
+ Content-Type:
+ - application/vnd.amazon.eventstream
+ status: 200 OK
+ code: 200
+ duration: 1.742548041s
diff --git a/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-sonnet/simple.yaml b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-sonnet/simple.yaml
new file mode 100644
index 000000000..300746d8a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-sonnet/simple.yaml
@@ -0,0 +1,32 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 211
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Say hi in Portuguese","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-sonnet-20240229-v1%3A0/invoke
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 248
+ body: '{"id":"msg_bdrk_01LRFVX3vkAe1gN871fWZ9TT","type":"message","role":"assistant","model":"claude-3-sonnet-20240229","content":[{"type":"text","text":"OlĆ”!"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":16,"output_tokens":7}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 994.951625ms
diff --git a/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-sonnet/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-sonnet/simple_streaming.yaml
new file mode 100644
index 000000000..ff6cc3c98
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-sonnet/simple_streaming.yaml
@@ -0,0 +1,77 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 211
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Say hi in Portuguese","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-sonnet-20240229-v1%3A0/invoke-with-response-stream
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: !!binary |
+ AAAB7gAAAEvYlO1qCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcG
+ xpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJs
+ SWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZl
+ ltUnlhMTh3TVVOQ1ozZHBjRzFZYlhSNlpIQjZiM3BhY25kMmQwc2lMQ0owZVhCbElqb2li
+ V1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWV
+ hWa1pTMHpMWE52Ym01bGRDMHlNREkwTURJeU9TSXNJbU52Ym5SbGJuUWlPbHRkTENKemRH
+ OXdYM0psWVhOdmJpSTZiblZzYkN3aWMzUnZjRjl6WlhGMVpXNWpaU0k2Ym5Wc2JDd2lkWE
+ 5oWjJVaU9uc2lhVzV3ZFhSZmRHOXJaVzV6SWpveE5pd2liM1YwY0hWMFgzUnZhMlZ1Y3lJ
+ Nk1uMTlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSk
+ tMTU5PUFFSU1RVVldYWVoifaXxLNMAAAEWAAAAS6DQ9vYLOmV2ZW50LXR5cGUHAAVjaHVu
+ aw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZX
+ ZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOXpkR0Z5ZENJ
+ c0ltbHVaR1Y0SWpvd0xDSmpiMjUwWlc1MFgySnNiMk5ySWpwN0luUjVjR1VpT2lKMFpYaD
+ BJaXdpZEdWNGRDSTZJaUo5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5
+ ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyMyJ9hcWOywAAAPoAAABLhqgPjQs6ZX
+ ZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTpt
+ ZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOW
+ liRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9p
+ ZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lKUGJDSjlmUT09IiwicCI6ImFiY2RlZmdoaW
+ prbG1ub3BxcnN0dXZ3eHl6QUIifRR2ulIAAAD7AAAAS7vIJj0LOmV2ZW50LXR5cGUHAAVj
+ aHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBw
+ AFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gw
+ WVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MF
+ lTSXNJblJsZUhRaU9pTERvU0o5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2
+ d3h5ekFCQyJ94G5ejAAAAQgAAABLfwDfFQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW
+ 50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0
+ ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVj
+ RJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFp
+ T2lJaEluMTkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0
+ xNTk9QUVJTVCJ9YBJX4gAAAMEAAABLUFmGGgs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250
+ ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYn
+ l0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5emRHOXdJaXdpYVc1a1pY
+ Z2lPakI5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREUifeLDB4cAAA
+ EPAAAAS80gAwULOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGlj
+ YXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam
+ 9pYldWemMyRm5aVjlrWld4MFlTSXNJbVJsYkhSaElqcDdJbk4wYjNCZmNtVmhjMjl1SWpv
+ aVpXNWtYM1IxY200aUxDSnpkRzl3WDNObGNYVmxibU5sSWpwdWRXeHNmU3dpZFhOaFoyVW
+ lPbnNpYjNWMGNIVjBYM1J2YTJWdWN5STZOMzE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3Bx
+ In1pE5R7AAABQQAAAEsq4+UtCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQ
+ cAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5
+ SjBlWEJsSWpvaWJXVnpjMkZuWlY5emRHOXdJaXdpWVcxaGVtOXVMV0psWkhKdlkyc3RhVz
+ UyYjJOaGRHbHZiazFsZEhKcFkzTWlPbnNpYVc1d2RYUlViMnRsYmtOdmRXNTBJam94Tml3
+ aWIzVjBjSFYwVkc5clpXNURiM1Z1ZENJNk55d2lhVzUyYjJOaGRHbHZia3hoZEdWdVkza2
+ lPalU0T1N3aVptbHljM1JDZVhSbFRHRjBaVzVqZVNJNk16UTRmWDA9IiwicCI6ImFiY2Rl
+ ZmdoaWprIn1lCEQa
+ headers:
+ Content-Type:
+ - application/vnd.amazon.eventstream
+ status: 200 OK
+ code: 200
+ duration: 504.27675ms
diff --git a/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-sonnet/tool.yaml b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-sonnet/tool.yaml
new file mode 100644
index 000000000..dc2cb10ab
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-sonnet/tool.yaml
@@ -0,0 +1,61 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 468
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-sonnet-20240229-v1%3A0/invoke
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 337
+ body: '{"id":"msg_bdrk_016xuAjCiRGnDVbfdDav8z4j","type":"message","role":"assistant","model":"claude-3-sonnet-20240229","content":[{"type":"tool_use","id":"toolu_bdrk_018kwMvGqtVmJGohuBCxtuuH","name":"weather","input":{"location":"Florence,Italy"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":240,"output_tokens":53}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.01528325s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 764
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"},{"content":[{"id":"toolu_bdrk_018kwMvGqtVmJGohuBCxtuuH","input":{"location":"Florence,Italy"},"name":"weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_bdrk_018kwMvGqtVmJGohuBCxtuuH","content":[{"text":"40 C","type":"text"}],"type":"tool_result"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-sonnet-20240229-v1%3A0/invoke
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: 285
+ body: '{"id":"msg_bdrk_01UgQxNiY3WUwwUBy8wQPCrt","type":"message","role":"assistant","model":"claude-3-sonnet-20240229","content":[{"type":"text","text":"The weather in Florence, Italy is 40°C."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":308,"output_tokens":16}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.93417325s
diff --git a/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-sonnet/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-sonnet/tool_streaming.yaml
new file mode 100644
index 000000000..3a458ee4b
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestBedrockCommon/bedrock-anthropic-claude-3-sonnet/tool_streaming.yaml
@@ -0,0 +1,208 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 468
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-sonnet-20240229-v1%3A0/invoke-with-response-stream
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: !!binary |
+ AAAByAAAAEuWFTfOCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcG
+ xpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJs
+ SWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZl
+ ltUnlhMTh3TVVOVVJIbEVOSFJaUkhOM1dqTXlSMnRhVFdjNE1WRWlMQ0owZVhCbElqb2li
+ V1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWV
+ hWa1pTMHpMWE52Ym01bGRDMHlNREkwTURJeU9TSXNJbU52Ym5SbGJuUWlPbHRkTENKemRH
+ OXdYM0psWVhOdmJpSTZiblZzYkN3aWMzUnZjRjl6WlhGMVpXNWpaU0k2Ym5Wc2JDd2lkWE
+ 5oWjJVaU9uc2lhVzV3ZFhSZmRHOXJaVzV6SWpveU5EQXNJbTkxZEhCMWRGOTBiMnRsYm5N
+ aU9qRjlmWDA9IiwicCI6ImFiY2RlZmdoaWprbG1uIn1bk3KsAAABOgAAAEuk4TTzCzpldm
+ VudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1l
+ c3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aW
+ JHOWphMTl6ZEdGeWRDSXNJbWx1WkdWNElqb3dMQ0pqYjI1MFpXNTBYMkpzYjJOcklqcDdJ
+ blI1Y0dVaU9pSjBiMjlzWDNWelpTSXNJbWxrSWpvaWRHOXZiSFZmWW1SeWExOHdNVFEzZF
+ dKR00yRnlUVkpJVkc0MFZYUkJOSEJsUlRRaUxDSnVZVzFsSWpvaWQyVmhkR2hsY2lJc0lt
+ bHVjSFYwSWpwN2ZYMTkiLCJwIjoiYWJjZGVmZ2gifR5cOTUAAAENAAAAS7fgUGULOmV2ZW
+ 50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVz
+ c2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYk
+ c5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWFX
+ NXdkWFJmYW5OdmJsOWtaV3gwWVNJc0luQmhjblJwWVd4ZmFuTnZiaUk2SWlKOWZRPT0iLC
+ JwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERSJ9hTLu0AAAAQoAAABLBcCM
+ dQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc2
+ 9uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdW
+ dWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQm
+ xJam9pYVc1d2RYUmZhbk52Ymw5a1pXeDBZU0lzSW5CaGNuUnBZV3hmYW5OdmJpSTZJbnRj
+ SW14dlkyRjBJbjE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0In3MEaHsAAABDwAAAE
+ vNIAMFCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9u
+ L2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOX
+ VkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUow
+ ZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNk
+ ltbHZibHdpT2lCY0lrWnNJbjE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dSJ9MlKj
+ YAAAARwAAABL6mDuVws6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcH
+ BsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhC
+ bElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeD
+ BZU0k2ZXlKMGVYQmxJam9pYVc1d2RYUmZhbk52Ymw5a1pXeDBZU0lzSW5CaGNuUnBZV3hm
+ YW5OdmJpSTZJbTl5Wlc1alpTeEpkR0ZzSW4xOSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcX
+ JzdHV2d3h5ekFCQ0RFRkdIIn3kS/QUAAAA/wAAAEtOSID9CzpldmVudC10eXBlBwAFY2h1
+ bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABW
+ V2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlT
+ SXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibD
+ lrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNklubGNJbjBpZlgwPSIsInAiOiJhYmNk
+ ZWZnaGlqa2xtIn0e+v+oAAAA2AAAAEs9qXPpCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbn
+ RlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJi
+ eXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTl6ZEc5d0lpd2lhVzVrWl
+ hnaU9qQjkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xN
+ Tk9QUVJTVFVWV1hZWjAxIn32VRefAAABIgAAAEv0ceiwCzpldmVudC10eXBlBwAFY2h1bm
+ sNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2
+ ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaWJXVnpjMkZuWlY5a1pXeDBZU0lzSW1SbGJIUm
+ hJanA3SW5OMGIzQmZjbVZoYzI5dUlqb2lkRzl2YkY5MWMyVWlMQ0p6ZEc5d1gzTmxjWFZs
+ Ym1ObElqcHVkV3hzZlN3aWRYTmhaMlVpT25zaWIzVjBjSFYwWDNSdmEyVnVjeUk2TlROOW
+ ZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUYifWTQLAYAAAFU
+ AAAAS4Lj/d8LOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYX
+ Rpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9p
+ YldWemMyRm5aVjl6ZEc5d0lpd2lZVzFoZW05dUxXSmxaSEp2WTJzdGFXNTJiMk5oZEdsdm
+ JrMWxkSEpwWTNNaU9uc2lhVzV3ZFhSVWIydGxia052ZFc1MElqb3lOREFzSW05MWRIQjFk
+ RlJ2YTJWdVEyOTFiblFpT2pNNUxDSnBiblp2WTJGMGFXOXVUR0YwWlc1amVTSTZNekE0Tn
+ l3aVptbHljM1JDZVhSbFRHRjBaVzVqZVNJNk16UXlmWDA9IiwicCI6ImFiY2RlZmdoaWpr
+ bG1ub3BxcnN0dXZ3eHl6In2+B8HI
+ headers:
+ Content-Type:
+ - application/vnd.amazon.eventstream
+ status: 200 OK
+ code: 200
+ duration: 490.224792ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 764
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"},{"content":[{"id":"toolu_bdrk_0147ubF3arMRHTn4UtA4peE4","input":{"location":"Florence,Italy"},"name":"weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_bdrk_0147ubF3arMRHTn4UtA4peE4","content":[{"text":"40 C","type":"text"}],"type":"tool_result"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"anthropic_version":"bedrock-2023-05-31"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-sonnet-20240229-v1%3A0/invoke-with-response-stream
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: !!binary |
+ AAAB1QAAAEsOZWT9CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcG
+ xpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJs
+ SWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZl
+ ltUnlhMTh3TVVKeE5IbFFabVk0ZUdOeGVUUm9aR04yTkZKMU5FTWlMQ0owZVhCbElqb2li
+ V1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWV
+ hWa1pTMHpMWE52Ym01bGRDMHlNREkwTURJeU9TSXNJbU52Ym5SbGJuUWlPbHRkTENKemRH
+ OXdYM0psWVhOdmJpSTZiblZzYkN3aWMzUnZjRjl6WlhGMVpXNWpaU0k2Ym5Wc2JDd2lkWE
+ 5oWjJVaU9uc2lhVzV3ZFhSZmRHOXJaVzV6SWpvek1EZ3NJbTkxZEhCMWRGOTBiMnRsYm5N
+ aU9qSjlmWDA9IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QSJ9MxX82gAAAO
+ YAAABLI7h1Dgs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNh
+ dGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2
+ lZMjl1ZEdWdWRGOWliRzlqYTE5emRHRnlkQ0lzSW1sdVpHVjRJam93TENKamIyNTBaVzUw
+ WDJKc2IyTnJJanA3SW5SNWNHVWlPaUowWlhoMElpd2lkR1Y0ZENJNklpSjlmUT09IiwicC
+ I6ImFiY2RlZmdoIn3SrDB1AAAA8wAAAEuLuG38CzpldmVudC10eXBlBwAFY2h1bmsNOmNv
+ bnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50ey
+ JieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1
+ WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbG
+ VIUWlPaUpjYmx4dVZHaGxJbjE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxIn0bCMYyAAAB
+ AAAAAEtPcJTUCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2
+ F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpv
+ aVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTST
+ ZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUlnZDJWaGRHaGxjaUo5
+ ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiJ9gKialAAAAOIAAABL1j
+ jTzgs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9q
+ c29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZE
+ dWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVY
+ QmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ2FXNGlmWDA9IiwicCI6ImFiY2
+ QifXBDECYAAADsAAAAS2kIba8LOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBl
+ BwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZX
+ lKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xD
+ SmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSWdSbX
+ h2Y21WdVkyVWlmWDA9IiwicCI6ImFiY2RlZiJ98lyl6AAAAOYAAABLI7h1Dgs6ZXZlbnQt
+ dHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYW
+ dlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlq
+ YTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNG
+ RGOWtaV3gwWVNJc0luUmxlSFFpT2lJc0luMTkiLCJwIjoiYWJjZGVmZ2hpamtsIn0N27mp
+ AAABBwAAAEv9UEjECzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcG
+ xpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJs
+ SWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MF
+ lTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUlnU1hSaGJIa2lm
+ WDA9IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSksifccMNp
+ oAAAEAAAAAS09wlNQLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBw
+ bGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQm
+ xJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gw
+ WVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSWdZM1Z5Y21WdW
+ RHeDVJbjE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6In1pHqATAAAA5AAA
+ AEtZeCZuCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW
+ 9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVky
+ OXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleU
+ owZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUlnYVhNaWZYMD0iLCJwIjoi
+ YWJjZGVmIn1D+kU3AAABAQAAAEtyEL1kCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbn
+ QtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRl
+ cyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNE
+ lqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlP
+ aUlnSW4xOSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE
+ 0ifXHHY7IAAAEJAAAAS0Jg9qULOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBl
+ BwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZX
+ lKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xD
+ SmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSTBNQ0
+ o5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1O
+ T1BRIn3XUit8AAAA+AAAAEv8aFztCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdH
+ lwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6
+ ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3
+ dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUxD
+ c0NKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoiffYMitIAAAEGAA
+ AAS8AwYXQLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRp
+ b24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWT
+ I5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5
+ SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSkRJbjE5IiwicCI6ImFiY2
+ RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSIn0nx3p/AAAA8AAA
+ AEvMGBcsCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW
+ 9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVky
+ OXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleU
+ owZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUl1SW4xOSIsInAiOiJhYmNk
+ ZWZnaGlqa2xtbm9wcXJzdHV2In1ME7fDAAAAtQAAAEtcC8AVCzpldmVudC10eXBlBwAFY2
+ h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcA
+ BWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTl6ZEc5d0
+ lpd2lhVzVrWlhnaU9qQjkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFycyJ9QnTMMwAAAQcA
+ AABL/VBIxAs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdG
+ lvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2li
+ V1Z6YzJGblpWOWtaV3gwWVNJc0ltUmxiSFJoSWpwN0luTjBiM0JmY21WaGMyOXVJam9pWl
+ c1a1gzUjFjbTRpTENKemRHOXdYM05sY1hWbGJtTmxJanB1ZFd4c2ZTd2lkWE5oWjJVaU9u
+ c2liM1YwY0hWMFgzUnZhMlZ1Y3lJNk1UZDlmUT09IiwicCI6ImFiY2RlIn1G7t0fAAABQA
+ AAAEsXg8ydCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0
+ aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaW
+ JXVnpjMkZuWlY5emRHOXdJaXdpWVcxaGVtOXVMV0psWkhKdlkyc3RhVzUyYjJOaGRHbHZi
+ azFsZEhKcFkzTWlPbnNpYVc1d2RYUlViMnRsYmtOdmRXNTBJam96TURnc0ltOTFkSEIxZE
+ ZSdmEyVnVRMjkxYm5RaU9qRTNMQ0pwYm5adlkyRjBhVzl1VEdGMFpXNWplU0k2TVRBd05p
+ d2labWx5YzNSQ2VYUmxUR0YwWlc1amVTSTZOVFl6ZlgwPSIsInAiOiJhYmNkZWYifepedk
+ U=
+ headers:
+ Content-Type:
+ - application/vnd.amazon.eventstream
+ status: 200 OK
+ code: 200
+ duration: 713.964541ms
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/multi_tool.yaml
new file mode 100644
index 000000000..2c28a0f95
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/multi_tool.yaml
@@ -0,0 +1,137 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 826
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "functionCall": {
+ "name": "add",
+ "args": {
+ "a": 2,
+ "b": 3
+ }
+ },
+ "thoughtSignature": "Cr4BAdHtim/Tq8T9XkqzcvcAqMXcurtfsNWvF+glFr+dbbGawdwSHuZ7mw9Xlm6KJ8Cie6v/uKr/LuTDVu+O1FD2kHVHH63fBYS4jt0jJdUs2xRL9+TdlgkrB1SyYzciPTdvzFrtCoM/iUQhtwohV0gr+3TWRYFtuOhW/WEDzYAJFjIPMftG0Jngtz2O59EN10sdngWQaAEYu2CUaPG47rqBITRumXdfX3+0nMCNpmbjqPCpJNg93O7EhMU8gJxs0g=="
+ },
+ {
+ "functionCall": {
+ "name": "multiply",
+ "args": {
+ "b": 3,
+ "a": 2
+ }
+ }
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0,
+ "finishMessage": "Model generated function call(s)."
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 125,
+ "candidatesTokenCount": 36,
+ "totalTokenCount": 200,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 125
+ }
+ ],
+ "thoughtsTokenCount": 39
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "responseId": "c6IdafipKOX-vdIPoJuZsAs"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 974.216125ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1437
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"},{"parts":[{"functionCall":{"args":{"a":2,"b":3},"id":"1","name":"add"},"thoughtSignature":"Cr4BAdHtim/Tq8T9XkqzcvcAqMXcurtfsNWvF+glFr+dbbGawdwSHuZ7mw9Xlm6KJ8Cie6v/uKr/LuTDVu+O1FD2kHVHH63fBYS4jt0jJdUs2xRL9+TdlgkrB1SyYzciPTdvzFrtCoM/iUQhtwohV0gr+3TWRYFtuOhW/WEDzYAJFjIPMftG0Jngtz2O59EN10sdngWQaAEYu2CUaPG47rqBITRumXdfX3+0nMCNpmbjqPCpJNg93O7EhMU8gJxs0g=="},{"functionCall":{"args":{"a":2,"b":3},"id":"2","name":"multiply"}}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"add","response":{"result":"5"}}},{"functionResponse":{"id":"2","name":"multiply","response":{"result":"6"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "The sum of 2 and 3 is 5 and the product of 2 and 3 is 6."
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 185,
+ "candidatesTokenCount": 24,
+ "totalTokenCount": 209,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 185
+ }
+ ]
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "responseId": "dKIdabyVFsrVvdIPuoSCuAk"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 693.548334ms
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/multi_tool_streaming.yaml
new file mode 100644
index 000000000..5c98e052a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/multi_tool_streaming.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 809
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. Always use both add and multiply at the same time."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"functionCall\": {\"name\": \"add\",\"args\": {\"b\": 3,\"a\": 2}},\"thoughtSignature\": \"CikB0e2KbzJ53cZQAbVmS3FT2mrSIPh4SqG9C0hmU6Af0IhPFXcFgoc5twptAdHtim8trKjd4oXwYT0oCz0ruME+ffJ75W/FCaehBo4LLnMuwRYanvHpWA8knHwPzDPADfYQCldBCzW+B2pcMTLxlHfoaaY+7mGGOqb9eyzyKxGJmmCBD80fHvEY0zNwjnLyLhrQjjLPjQOJJwpnAdHtim/XR83WyBkpOGrXLvmZ2ZNz16pdlWavvk2U+RyzJH2ca5szuZ3ZlepealN3RCzYHo2vUpwBqPKx2NGNVTfI8jUAueIO8tb/0Z+VJHpktNds5qCJgvCZUfQwN8MEWO0vMOgqww==\"},{\"functionCall\": {\"name\": \"multiply\",\"args\": {\"a\": 2,\"b\": 3}}}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0,\"finishMessage\": \"Model generated function call(s).\"}],\"usageMetadata\": {\"promptTokenCount\": 121,\"candidatesTokenCount\": 36,\"totalTokenCount\": 195,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 121}],\"thoughtsTokenCount\": 38},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"dKIdacS5OILaxs0PwvHjwQ4\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 897.297ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1508
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"},{"parts":[{"functionCall":{"args":{"a":2,"b":3},"id":"1","name":"add"},"thoughtSignature":"CikB0e2KbzJ53cZQAbVmS3FT2mrSIPh4SqG9C0hmU6Af0IhPFXcFgoc5twptAdHtim8trKjd4oXwYT0oCz0ruME+ffJ75W/FCaehBo4LLnMuwRYanvHpWA8knHwPzDPADfYQCldBCzW+B2pcMTLxlHfoaaY+7mGGOqb9eyzyKxGJmmCBD80fHvEY0zNwjnLyLhrQjjLPjQOJJwpnAdHtim/XR83WyBkpOGrXLvmZ2ZNz16pdlWavvk2U+RyzJH2ca5szuZ3ZlepealN3RCzYHo2vUpwBqPKx2NGNVTfI8jUAueIO8tb/0Z+VJHpktNds5qCJgvCZUfQwN8MEWO0vMOgqww=="},{"functionCall":{"args":{"a":2,"b":3},"id":"2","name":"multiply"}}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"add","response":{"result":"5"}}},{"functionResponse":{"id":"2","name":"multiply","response":{"result":"6"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. Always use both add and multiply at the same time."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"The sum of \"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 217,\"candidatesTokenCount\": 3,\"totalTokenCount\": 220,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 217}]},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"daIdacGIO4XlvdIPwJX1gAk\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"2 and 3 is 5. The product of 2 and 3 is\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 217,\"candidatesTokenCount\": 20,\"totalTokenCount\": 237,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 217}]},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"daIdacGIO4XlvdIPwJX1gAk\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \" 6.\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 217,\"candidatesTokenCount\": 22,\"totalTokenCount\": 239,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 217}]},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"daIdacGIO4XlvdIPwJX1gAk\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 691.66875ms
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/simple.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/simple.yaml
new file mode 100644
index 000000000..027c1ebd7
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/simple.yaml
@@ -0,0 +1,62 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 202
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Say hi in Portuguese"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "OlĆ”!"
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 11,
+ "candidatesTokenCount": 2,
+ "totalTokenCount": 35,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 11
+ }
+ ],
+ "thoughtsTokenCount": 22
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "responseId": "bqIdadvABK-8xN8Plpr0oAY"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 517.171875ms
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/simple_streaming.yaml
new file mode 100644
index 000000000..0ca5d57c2
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/simple_streaming.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 202
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Say hi in Portuguese"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"}}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"OlĆ”! In Portuguese, you can say:\\n\\n**OlĆ”!**\\n\\nIt's a versatile greeting that works for \\\"hi,\\\" \\\"hello,\\\" and even \\\"hey.\\\"\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 11,\"candidatesTokenCount\": 35,\"totalTokenCount\": 78,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 11}],\"thoughtsTokenCount\": 32},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"bqIdacLAGozKvdIP5Nu3oAg\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 733.998792ms
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/tool.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/tool.yaml
new file mode 100644
index 000000000..f6f5ceb0a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/tool.yaml
@@ -0,0 +1,127 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 509
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "functionCall": {
+ "name": "weather",
+ "args": {
+ "location": "Florence, Italy"
+ }
+ },
+ "thoughtSignature": "CoICAdHtim+oSIAY8uUYR6EfmWAxA3fQg7sAam3Jw4sK1xvXAvTmomotsL1uIgSO4Kx79F3+SQ3iVydWojoLVRBdLbdc+U0K2rXqTzc739H/3nUgqnfYELuBXKYE7W5ON5r2y2LzanK4lbUpHh8M4PYAtY8yIn8wonpr1KL+Ec6ykafkiT4nGHQHmmqndKKsdkLXboxtBxeKp2ZV0aCv1NiNvuwz0kucUx1AXBTI2SUpvAEsz2BfpmJg1i3eBwHtCyuz/I7/K2hqWHsO1NY1M0mL2c+1uwRhwTO5kNJ2i5q+la5MP6GN4Un5yceWmI4LNWInHfL0PUJ1MiCkurtsFMGqNA5+"
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0,
+ "finishMessage": "Model generated function call(s)."
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 54,
+ "candidatesTokenCount": 15,
+ "totalTokenCount": 122,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 54
+ }
+ ],
+ "thoughtsTokenCount": 53
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "responseId": "b6IdafT6Kd6evdIPrZ2kqAU"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 903.990542ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1093
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"location":"Florence, Italy"},"id":"1","name":"weather"},"thoughtSignature":"CoICAdHtim+oSIAY8uUYR6EfmWAxA3fQg7sAam3Jw4sK1xvXAvTmomotsL1uIgSO4Kx79F3+SQ3iVydWojoLVRBdLbdc+U0K2rXqTzc739H/3nUgqnfYELuBXKYE7W5ON5r2y2LzanK4lbUpHh8M4PYAtY8yIn8wonpr1KL+Ec6ykafkiT4nGHQHmmqndKKsdkLXboxtBxeKp2ZV0aCv1NiNvuwz0kucUx1AXBTI2SUpvAEsz2BfpmJg1i3eBwHtCyuz/I7/K2hqWHsO1NY1M0mL2c+1uwRhwTO5kNJ2i5q+la5MP6GN4Un5yceWmI4LNWInHfL0PUJ1MiCkurtsFMGqNA5+"}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"weather","response":{"result":"40 C"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "The weather in Florence, Italy is 40 C."
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 84,
+ "candidatesTokenCount": 12,
+ "totalTokenCount": 96,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 84
+ }
+ ]
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "responseId": "cKIdaYmFE-73vdIPyu-CiQ4"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 580.239833ms
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/tool_streaming.yaml
new file mode 100644
index 000000000..031d77063
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-flash/tool_streaming.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 509
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"functionCall\": {\"name\": \"weather\",\"args\": {\"location\": \"Florence, Italy\"}},\"thoughtSignature\": \"CiQB0e2Kb5hLxW4oJvRVAtEyLSHknL6TrwoTlUrzV/NIKu+R2z8KYwHR7YpvSN4fng8omWFL8Aqjsl9X3H+kgDzmS7IrsQLTYrFyl7mDqVImhz66isD523DqKjTNM+VDowi7QGeoVmSGy4+iDSNmK4JMcn8hMxHExBdm1BDyf2m5oXW+6Q2hVWscoQqJAgHR7YpvKGTVtc/SBxH4DcGgHUE2vbnfSF8icr79c/9Z4JUVIM8e3vDxVSlSoXqSyOBIjCYx75OWcokqKhKSbksYQhgWj2OBK4yqkjgDn4Ei6a3mO4m1B+fCX39c73spRSK+0RCGfPdkmL0iTB+lTB4QjKZZGqjEe87oL4rt26ZlndfpPRmdqqqdC4MVnRDqXOO4xrSr4A+n27MCr/mzu0FGg2ld13WUuu42nvb+pSgIoQC1ARz5CsDhTfXp2vFywCpbFzK1w61QJSgyjcBph/SljYIVLLwcY8uaWr1ZLIc+6sdZU9g3n2jlZ/HIR9zc62qdIcdLWLaqfuRKfRQXykjOAJwwMziZ7ncKIwHR7YpvVfOT+ooTKaMyWqreuH0LElgmp0tV5T5M+SoXjTTp\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0,\"finishMessage\": \"Model generated function call(s).\"}],\"usageMetadata\": {\"promptTokenCount\": 54,\"candidatesTokenCount\": 15,\"totalTokenCount\": 139,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 54}],\"thoughtsTokenCount\": 70},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"caIdad66Iaq-vdIPlaK54Ak\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.638936291s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1337
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"location":"Florence, Italy"},"id":"1","name":"weather"},"thoughtSignature":"CiQB0e2Kb5hLxW4oJvRVAtEyLSHknL6TrwoTlUrzV/NIKu+R2z8KYwHR7YpvSN4fng8omWFL8Aqjsl9X3H+kgDzmS7IrsQLTYrFyl7mDqVImhz66isD523DqKjTNM+VDowi7QGeoVmSGy4+iDSNmK4JMcn8hMxHExBdm1BDyf2m5oXW+6Q2hVWscoQqJAgHR7YpvKGTVtc/SBxH4DcGgHUE2vbnfSF8icr79c/9Z4JUVIM8e3vDxVSlSoXqSyOBIjCYx75OWcokqKhKSbksYQhgWj2OBK4yqkjgDn4Ei6a3mO4m1B+fCX39c73spRSK+0RCGfPdkmL0iTB+lTB4QjKZZGqjEe87oL4rt26ZlndfpPRmdqqqdC4MVnRDqXOO4xrSr4A+n27MCr/mzu0FGg2ld13WUuu42nvb+pSgIoQC1ARz5CsDhTfXp2vFywCpbFzK1w61QJSgyjcBph/SljYIVLLwcY8uaWr1ZLIc+6sdZU9g3n2jlZ/HIR9zc62qdIcdLWLaqfuRKfRQXykjOAJwwMziZ7ncKIwHR7YpvVfOT+ooTKaMyWqreuH0LElgmp0tV5T5M+SoXjTTp"}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"weather","response":{"result":"40 C"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"The weather in Florence\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 152,\"candidatesTokenCount\": 4,\"totalTokenCount\": 156,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 152}]},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"cqIdaf_pKt20xN8P1r_twQg\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \", Italy is 40 C.\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 152,\"candidatesTokenCount\": 12,\"totalTokenCount\": 164,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 152}]},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"cqIdaf_pKt20xN8P1r_twQg\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 744.812791ms
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/multi_tool.yaml
new file mode 100644
index 000000000..bc03680e1
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/multi_tool.yaml
@@ -0,0 +1,137 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 826
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "functionCall": {
+ "name": "add",
+ "args": {
+ "a": 2,
+ "b": 3
+ }
+ },
+ "thoughtSignature": "Ct4DAdHtim86WQIPk3bh2XALNHL2XEV9TyeNz9k+Z06RPzFlt9c10RhGIIiLApE4rqlKdDjjly0ZJY0+UYfFkA1ZnAYgz8v/GnqX822cM936bMf2yQ3BLMQn9KYN2iabIhiS0wy9eF2MYE/xjlaYrAfH6Ek6/gmyTSjmstOU0/ipD+XcmqRiryIEEDINK4SjFK4aGAy6pkVYtNPT/1mm5l01Nr8b6IJaPq5YyPTHud14tw0ZnJaqff0TfM4t0NLYV0cgFTCR9phlWyR2ByE0xLigMSVOwNqWow4JPanV4CmxliGwuzJzrhhc7Olc9oIX0CVE8sLJwgH2I4lCUBx4g2JxvLI4flrY4d3nVbAbOtjLgAB0jQO24VL1tjRM+N/TP1KcdGKMhqLvv8TPAuKLsuoreI70Ggfph0ZstnQt/CgRIrvdG1q1j6+3S5H9l+5OL1JHwqPNfEcxawFtWbE1etM0EHXG0c1lRa090y+e2lLMDxNUyiUXl9UfLeQR0dCWqW+lL98DBYpT8eVF4VUCaxKR2uDlKuoBrP9KchziKXh4W61Guj3dGXSOQvo3UrQXna80k0rcIWnJ93Ri2/b6zjWUJoGPPr74qAID2ld3dA4DwsSG2oaVZ9SkDuO1RfdkUA=="
+ },
+ {
+ "functionCall": {
+ "name": "multiply",
+ "args": {
+ "b": 3,
+ "a": 2
+ }
+ }
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0,
+ "finishMessage": "Model generated function call(s)."
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 125,
+ "candidatesTokenCount": 36,
+ "totalTokenCount": 292,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 125
+ }
+ ],
+ "thoughtsTokenCount": 131
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "responseId": "kKIdaerxBqH6xs0P87WrgAk"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 2.442287917s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1821
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"},{"parts":[{"functionCall":{"args":{"a":2,"b":3},"id":"1","name":"add"},"thoughtSignature":"Ct4DAdHtim86WQIPk3bh2XALNHL2XEV9TyeNz9k+Z06RPzFlt9c10RhGIIiLApE4rqlKdDjjly0ZJY0+UYfFkA1ZnAYgz8v/GnqX822cM936bMf2yQ3BLMQn9KYN2iabIhiS0wy9eF2MYE/xjlaYrAfH6Ek6/gmyTSjmstOU0/ipD+XcmqRiryIEEDINK4SjFK4aGAy6pkVYtNPT/1mm5l01Nr8b6IJaPq5YyPTHud14tw0ZnJaqff0TfM4t0NLYV0cgFTCR9phlWyR2ByE0xLigMSVOwNqWow4JPanV4CmxliGwuzJzrhhc7Olc9oIX0CVE8sLJwgH2I4lCUBx4g2JxvLI4flrY4d3nVbAbOtjLgAB0jQO24VL1tjRM+N/TP1KcdGKMhqLvv8TPAuKLsuoreI70Ggfph0ZstnQt/CgRIrvdG1q1j6+3S5H9l+5OL1JHwqPNfEcxawFtWbE1etM0EHXG0c1lRa090y+e2lLMDxNUyiUXl9UfLeQR0dCWqW+lL98DBYpT8eVF4VUCaxKR2uDlKuoBrP9KchziKXh4W61Guj3dGXSOQvo3UrQXna80k0rcIWnJ93Ri2/b6zjWUJoGPPr74qAID2ld3dA4DwsSG2oaVZ9SkDuO1RfdkUA=="},{"functionCall":{"args":{"a":2,"b":3},"id":"2","name":"multiply"}}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"add","response":{"result":"5"}}},{"functionResponse":{"id":"2","name":"multiply","response":{"result":"6"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "The sum of 2 and 3 is 5. The product of 2 and 3 is 6.\n"
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 185,
+ "candidatesTokenCount": 24,
+ "totalTokenCount": 209,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 185
+ }
+ ]
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "responseId": "kqIdaYyhHaq-vdIPkaK54Ak"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 2.379932167s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/multi_tool_streaming.yaml
new file mode 100644
index 000000000..ca92c65f7
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/multi_tool_streaming.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 809
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. Always use both add and multiply at the same time."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"functionCall\": {\"name\": \"add\",\"args\": {\"a\": 2,\"b\": 3}},\"thoughtSignature\": \"CiQB0e2Kbx/zJCGX4QRM1YjdG/0vM0O4q138GSgP9DFjPo5BvxgKXgHR7Ypvpmm3CK4gVVZtV0AvJ5MhonziwhvNMCDxg+jdrww42W8UHrTuM1cvExKrM1WsQkHnTo1PUMcUH9Ju006B1GZbgQvs3J8svt8NYJgh0WNDt8UHPO6b6VGSss4KkQEB0e2Kb68CHsB09XAnHX229MS+YrPraiD8fPqMxVLLkc2FuCR5+fI7A+kzP91qGr92hzdvYlksVeLRy5a5n1LEQmnxxFXtY8xsKDaBXDUlIvdK7VEUb60Gn9vss03eABVgI6cmwR46HFzDAvSwsl3sWtP2U4qoHTTNZ4Dt36pl/S4nxB7Lp14pcLP7sOLZkowTCoEBAdHtim8Pb7C65eIUdYFOqURU6C1ur0uJa+zVoM2/bIsSO8LXUpvdLcOM6mPhIxLisPAwhhk35D3vgnRW+luq0e8A0VsKo6AhR0NAsIN3IQnC0+vreFuIzaCYOpNuHlYXjNVbfX/CbLHsIF0+waFfbkF2ZO3GFOji0b0BTsrXoheuCo4BAdHtim8nuIkYXJNfCkRLNH8/SIGCEBIFitZzjcwzbfOLkNm/ibVwVYY8D838Gii33aJN1DyuxE4k3A+c0W8pe/YXPkdV9SXSsQ+N8KDwKRNjgjpog9psIBwG+7GfNkk3ImBvN1NwptAWKOgk5AO4dt0K7aGzWpdN+a8CfHlIjv3SKlt8AHvS82uRqv235QpmAdHtim9SMTkv6plfjBrsVRQqxAgl0jx8LVeR230NGsiTtc79hjGV1U/s2pDAdJDZp717tUJ0qL7L222pR5YbwtxqZZKBUl/ouOKOaYbZwXfuVAfL6U22ByxWWzjqXv360BthO8IVCogBAdHtim+nET8Gb9Oab/o8GshmXqUY2b7baafXDOcauibkZcx71dgfKxCnCm22wy1rTGG1Nz0nsJTPsAn2cVw+8XcWqSzpwDTRlxqnLu4/XoxjgE2nWADt8xTOgp5wFd4nw9tIs+5G2ApE2wCpRZ2cVWo2m/3onEfP9+GUJutE5YEzyXgThr7nGgpOAdHtim+uYwn7607G/Pg+uC0cCWm7SJZxDYhohc40e5tqDXxIXfixJ5CYUiKURKX658TamimYkiBr8FGZs2XkdMKkn1gFbQj4tZjpHu+R\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 121,\"candidatesTokenCount\": 18,\"totalTokenCount\": 308,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 121}],\"thoughtsTokenCount\": 169},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"k6Idad-8PLLUvdIP9tDr8As\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"functionCall\": {\"name\": \"multiply\",\"args\": {\"b\": 3,\"a\": 2}}}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0,\"finishMessage\": \"Model generated function call(s).\"}],\"usageMetadata\": {\"promptTokenCount\": 121,\"candidatesTokenCount\": 36,\"totalTokenCount\": 326,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 121}],\"thoughtsTokenCount\": 169},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"k6Idad-8PLLUvdIP9tDr8As\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.96572975s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2336
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"},{"parts":[{"functionCall":{"args":{"a":2,"b":3},"id":"1","name":"add"},"thoughtSignature":"CiQB0e2Kbx/zJCGX4QRM1YjdG/0vM0O4q138GSgP9DFjPo5BvxgKXgHR7Ypvpmm3CK4gVVZtV0AvJ5MhonziwhvNMCDxg+jdrww42W8UHrTuM1cvExKrM1WsQkHnTo1PUMcUH9Ju006B1GZbgQvs3J8svt8NYJgh0WNDt8UHPO6b6VGSss4KkQEB0e2Kb68CHsB09XAnHX229MS+YrPraiD8fPqMxVLLkc2FuCR5+fI7A+kzP91qGr92hzdvYlksVeLRy5a5n1LEQmnxxFXtY8xsKDaBXDUlIvdK7VEUb60Gn9vss03eABVgI6cmwR46HFzDAvSwsl3sWtP2U4qoHTTNZ4Dt36pl/S4nxB7Lp14pcLP7sOLZkowTCoEBAdHtim8Pb7C65eIUdYFOqURU6C1ur0uJa+zVoM2/bIsSO8LXUpvdLcOM6mPhIxLisPAwhhk35D3vgnRW+luq0e8A0VsKo6AhR0NAsIN3IQnC0+vreFuIzaCYOpNuHlYXjNVbfX/CbLHsIF0+waFfbkF2ZO3GFOji0b0BTsrXoheuCo4BAdHtim8nuIkYXJNfCkRLNH8/SIGCEBIFitZzjcwzbfOLkNm/ibVwVYY8D838Gii33aJN1DyuxE4k3A+c0W8pe/YXPkdV9SXSsQ+N8KDwKRNjgjpog9psIBwG+7GfNkk3ImBvN1NwptAWKOgk5AO4dt0K7aGzWpdN+a8CfHlIjv3SKlt8AHvS82uRqv235QpmAdHtim9SMTkv6plfjBrsVRQqxAgl0jx8LVeR230NGsiTtc79hjGV1U/s2pDAdJDZp717tUJ0qL7L222pR5YbwtxqZZKBUl/ouOKOaYbZwXfuVAfL6U22ByxWWzjqXv360BthO8IVCogBAdHtim+nET8Gb9Oab/o8GshmXqUY2b7baafXDOcauibkZcx71dgfKxCnCm22wy1rTGG1Nz0nsJTPsAn2cVw+8XcWqSzpwDTRlxqnLu4/XoxjgE2nWADt8xTOgp5wFd4nw9tIs+5G2ApE2wCpRZ2cVWo2m/3onEfP9+GUJutE5YEzyXgThr7nGgpOAdHtim+uYwn7607G/Pg+uC0cCWm7SJZxDYhohc40e5tqDXxIXfixJ5CYUiKURKX658TamimYkiBr8FGZs2XkdMKkn1gFbQj4tZjpHu+R"},{"functionCall":{"args":{"a":2,"b":3},"id":"2","name":"multiply"}}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"add","response":{"result":"5"}}},{"functionResponse":{"id":"2","name":"multiply","response":{"result":"6"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. Always use both add and multiply at the same time."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"The\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 348,\"candidatesTokenCount\": 1,\"totalTokenCount\": 349,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 348}]},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"lqIdafyeNI7WvdIP2uCBoAw\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \" sum of 2 and 3 is 5, and the product of 2 and \"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 348,\"candidatesTokenCount\": 19,\"totalTokenCount\": 367,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 348}]},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"lqIdafyeNI7WvdIP2uCBoAw\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"3 is 6.\\n\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 348,\"candidatesTokenCount\": 24,\"totalTokenCount\": 372,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 348}]},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"lqIdafyeNI7WvdIP2uCBoAw\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.420692s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/simple.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/simple.yaml
new file mode 100644
index 000000000..409caf5ea
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/simple.yaml
@@ -0,0 +1,62 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 202
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Say hi in Portuguese"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "Of course!\n\nThe most common ways to say \"hi\" in Portuguese are:\n\n* **OlĆ”** (oh-LAH) - This is the direct translation of \"hello\" and can be used in any situation, formal or informal.\n* **Oi** (oy) - This is more informal and very common, just like \"hi\" in English.\n\nYou can also use:\n\n* **Tudo bem?** (too-doh beng?) - Which means \"How are you?\" or \"Is everything good?\" and is a very common way to greet someone."
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 11,
+ "candidatesTokenCount": 122,
+ "totalTokenCount": 849,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 11
+ }
+ ],
+ "thoughtsTokenCount": 716
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "responseId": "fqIdabztHPjXxs0P146HoQk"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 8.426214208s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/simple_streaming.yaml
new file mode 100644
index 000000000..d384ea4d4
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/simple_streaming.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 202
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Say hi in Portuguese"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"}}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"Of course!\\n\\nThe most common ways to say \\\"hi\\\" in Portuguese are:\\n\\n* **OlĆ”!** (\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 11,\"candidatesTokenCount\": 25,\"totalTokenCount\": 645,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 11}],\"thoughtsTokenCount\": 609},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"gKIdacu9Ct_UvdIPu_e3-QY\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"This is the direct translation of \\\"hello\\\" and works in any situation.)\\n* **Oi!** (This\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 11,\"candidatesTokenCount\": 49,\"totalTokenCount\": 669,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 11}],\"thoughtsTokenCount\": 609},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"gKIdacu9Ct_UvdIPu_e3-QY\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \" is more informal and very common, like saying \\\"hi\\\" or \\\"hey.\\\")\\n\\nYou can also use greetings based on the\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 11,\"candidatesTokenCount\": 74,\"totalTokenCount\": 694,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 11}],\"thoughtsTokenCount\": 609},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"gKIdacu9Ct_UvdIPu_e3-QY\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \" time of day:\\n\\n* **Bom dia** (Good morning)\\n* **Boa tarde** (Good\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 11,\"candidatesTokenCount\": 98,\"totalTokenCount\": 718,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 11}],\"thoughtsTokenCount\": 609},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"gKIdacu9Ct_UvdIPu_e3-QY\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \" afternoon)\\n* **Boa noite** (Good evening / Good night)\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 11,\"candidatesTokenCount\": 115,\"totalTokenCount\": 735,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 11}],\"thoughtsTokenCount\": 609},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"gKIdacu9Ct_UvdIPu_e3-QY\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 7.118728083s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/tool.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/tool.yaml
new file mode 100644
index 000000000..3042c2ee8
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/tool.yaml
@@ -0,0 +1,127 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 509
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "functionCall": {
+ "name": "weather",
+ "args": {
+ "location": "Florence, Italy"
+ }
+ },
+ "thoughtSignature": "CtcDAdHtim8sltjSbCOxCM3sW652tUKKCiplDIoViEhKUuXpAUkg8vvhGpNwIBQdUOU091dd13FYdNYoTg/N62xtEIbin8xsVkDAhEBNTyciVa1cUORxFwTjID5b4z8/byy0Zf/e6sbKXMxbf9BpAVMHQW0mF6Yz82BQsczMi3B00lOO+0VV82ClVs4tBXYf7o3kekAAVD+XGCfuB/YGr9V6CeJCMXc8+gVpLIFS4DaPlNMoG3Lv4PnZp4beJ4puuIxh+3ipmGv8hJKAwUFAZmuU/knnUMqc09ddXtJdPKyssWbuR51SIU49+eVtxOib43fUOILlOO+J0oukfCSt2JS6EuVVSNYDMC7HOUkkY9T7V9IbCEtiuL42gvWbCAEwbta/QuGH1L9emajt2yiX+bIcuCl3GuRU0wQ/AB4mMBFwmnATUiaEKAmtSpiSvHy20SUHMh/KPNEOfQ0J6IyBWWhKhEaiAezRaKZSao6g68ymM5xOAyY0Vkrq3pWeUjboR9Z65I/tKiE2Qs6PuQJWI1sL67D9a885x10iR6NpaJyETpOYqGDqjZ3zs8ZiibLy0iitwibDwXzJyCLrJzEoTRmtotxoSkTm2wQVUpVpQzZBl4pzMbY2CRoR"
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0,
+ "finishMessage": "Model generated function call(s)."
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 54,
+ "candidatesTokenCount": 15,
+ "totalTokenCount": 181,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 54
+ }
+ ],
+ "thoughtsTokenCount": 112
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "responseId": "iKIdafbaFtX8vdIPueXoyAk"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 2.134031542s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1377
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"location":"Florence, Italy"},"id":"1","name":"weather"},"thoughtSignature":"CtcDAdHtim8sltjSbCOxCM3sW652tUKKCiplDIoViEhKUuXpAUkg8vvhGpNwIBQdUOU091dd13FYdNYoTg/N62xtEIbin8xsVkDAhEBNTyciVa1cUORxFwTjID5b4z8/byy0Zf/e6sbKXMxbf9BpAVMHQW0mF6Yz82BQsczMi3B00lOO+0VV82ClVs4tBXYf7o3kekAAVD+XGCfuB/YGr9V6CeJCMXc8+gVpLIFS4DaPlNMoG3Lv4PnZp4beJ4puuIxh+3ipmGv8hJKAwUFAZmuU/knnUMqc09ddXtJdPKyssWbuR51SIU49+eVtxOib43fUOILlOO+J0oukfCSt2JS6EuVVSNYDMC7HOUkkY9T7V9IbCEtiuL42gvWbCAEwbta/QuGH1L9emajt2yiX+bIcuCl3GuRU0wQ/AB4mMBFwmnATUiaEKAmtSpiSvHy20SUHMh/KPNEOfQ0J6IyBWWhKhEaiAezRaKZSao6g68ymM5xOAyY0Vkrq3pWeUjboR9Z65I/tKiE2Qs6PuQJWI1sL67D9a885x10iR6NpaJyETpOYqGDqjZ3zs8ZiibLy0iitwibDwXzJyCLrJzEoTRmtotxoSkTm2wQVUpVpQzZBl4pzMbY2CRoR"}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"weather","response":{"result":"40 C"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "The weather in Florence, Italy is 40 C."
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 84,
+ "candidatesTokenCount": 12,
+ "totalTokenCount": 96,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 84
+ }
+ ]
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "responseId": "iqIdaYfpG6_9xN8Pgt6ymQk"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 2.067662125s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/tool_streaming.yaml
new file mode 100644
index 000000000..ec87ed359
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-2.5-pro/tool_streaming.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 509
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"functionCall\": {\"name\": \"weather\",\"args\": {\"location\": \"Florence, Italy\"}},\"thoughtSignature\": \"CiIB0e2Kb8A87l6fcJFqiyFOsaqJQbuIyvqWWGMyVLlvR5BOCmcB0e2KbzIGGc8QCp2X4zQ5F7dQvkx1zJbHigOjmr6JMhp1opsOUlDm2O34WqYMy1TooaTT5N/h3ufeU3dl5Ss2qP6omWLzzoF4kXUCbwcvIgTiqDayYrPfwHx93XC7rU1nG4aTBIMtCocBAdHtim/dvxkuVr2NRUIhqXz/yVDiYbflnMhp6AqlkPkqChqNrP6BOzT5kw9Vh6cx8NrTCTdd+oqM01fXQC+EuV4nD52dDrViwxVoMmiObnjvL1kdkMN+mlXsdwQMXbbZuZG0KwY5baJR5OKgTlXW7nOgzjYo2iEGk9g5V6jF6F0ZBCKMUWWcCoABAdHtim/3KIej0FWXxbVioSBF/JIkCmmTHOFTT+1/VNK1YKl7nZ6e6OarSZ9Q1Qam4bf5Aw4hg0JmRPI8UpB3SrFva3dkfHceyPIWBbjtmIEawNZaSnCv+oYXJGdQze8bUSZ3bD6HnDhju2eLNqRzVEAkYwCQPD8DjmAbGPdN4j0KhAEB0e2Kb0BS3VRBfKzWnObbM9W8DaK8rHpUWYE/gUfOEHEWQTT4cJe2ilhneXgGffnK24wYtqIbyGnbZnBcpkifQHhTJAz9tEAToRfckSr2qiDdyxlxtmuzLopPgjWLTO4S/hNAKKOrkcZkyvkfQaEPnvoDNutWb5GNLs8RkAkUeXTzlbcKYgHR7YpvgZXPWWUaxQ3ehM2VoAPQ6RV2cQHT+95ahkTE6PzT2PKJ/m5dgAohTAX7NEsG74SOFrdZWtnspq9T23ebHIyyxwyTbsmmzaxsPw/nEI2KpAfc+brA0lvP740peGWC\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0,\"finishMessage\": \"Model generated function call(s).\"}],\"usageMetadata\": {\"promptTokenCount\": 54,\"candidatesTokenCount\": 15,\"totalTokenCount\": 176,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 54}],\"thoughtsTokenCount\": 107},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"i6IdafXaGKePvdIPj5TpsQk\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.958855542s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1605
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"location":"Florence, Italy"},"id":"1","name":"weather"},"thoughtSignature":"CiIB0e2Kb8A87l6fcJFqiyFOsaqJQbuIyvqWWGMyVLlvR5BOCmcB0e2KbzIGGc8QCp2X4zQ5F7dQvkx1zJbHigOjmr6JMhp1opsOUlDm2O34WqYMy1TooaTT5N/h3ufeU3dl5Ss2qP6omWLzzoF4kXUCbwcvIgTiqDayYrPfwHx93XC7rU1nG4aTBIMtCocBAdHtim/dvxkuVr2NRUIhqXz/yVDiYbflnMhp6AqlkPkqChqNrP6BOzT5kw9Vh6cx8NrTCTdd+oqM01fXQC+EuV4nD52dDrViwxVoMmiObnjvL1kdkMN+mlXsdwQMXbbZuZG0KwY5baJR5OKgTlXW7nOgzjYo2iEGk9g5V6jF6F0ZBCKMUWWcCoABAdHtim/3KIej0FWXxbVioSBF/JIkCmmTHOFTT+1/VNK1YKl7nZ6e6OarSZ9Q1Qam4bf5Aw4hg0JmRPI8UpB3SrFva3dkfHceyPIWBbjtmIEawNZaSnCv+oYXJGdQze8bUSZ3bD6HnDhju2eLNqRzVEAkYwCQPD8DjmAbGPdN4j0KhAEB0e2Kb0BS3VRBfKzWnObbM9W8DaK8rHpUWYE/gUfOEHEWQTT4cJe2ilhneXgGffnK24wYtqIbyGnbZnBcpkifQHhTJAz9tEAToRfckSr2qiDdyxlxtmuzLopPgjWLTO4S/hNAKKOrkcZkyvkfQaEPnvoDNutWb5GNLs8RkAkUeXTzlbcKYgHR7YpvgZXPWWUaxQ3ehM2VoAPQ6RV2cQHT+95ahkTE6PzT2PKJ/m5dgAohTAX7NEsG74SOFrdZWtnspq9T23ebHIyyxwyTbsmmzaxsPw/nEI2KpAfc+brA0lvP740peGWC"}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"weather","response":{"result":"40 C"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"The weather in Florence\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 189,\"candidatesTokenCount\": 4,\"totalTokenCount\": 193,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 189}]},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"jaIdafjSJqTyxs0PnYinqAk\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \", Italy is 40 C. \\n\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 189,\"candidatesTokenCount\": 12,\"totalTokenCount\": 201,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 189}]},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"jaIdafjSJqTyxs0PnYinqAk\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.21722675s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/multi_tool.yaml
new file mode 100644
index 000000000..cd2d444cf
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/multi_tool.yaml
@@ -0,0 +1,137 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 826
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "functionCall": {
+ "name": "add",
+ "args": {
+ "b": 3,
+ "a": 2
+ }
+ },
+ "thoughtSignature": "Ep8DCpwDAdHtim9QdO0y9bZ65Rujicbol+wCUJKbtFVKI8R2aVL5g9KNn25HRk9RQTnn6Mf/bHwNDvm17S/NkwMNRHTnsrgsFhCnID3D3UUhs2a0PJAw2qr4I2JkLlDxSarHaYQL8FkzDJCyEfaKHa4wPEFCTQL4DYtVutBbO5/f8meUiUhZxBBuKshtXWlqO0ecRIKJ1UD+wMZ0BlFGdJGYoVVpYFlbk3/MJzmKzy21oDuzYLPSpHFi79QB6QucplXCYu37zxdYlzr6Hq5aGYf2Cw6qKr5j8F85I+zX5S0MPfVdK68nuPC4qb/qYGRUhMHzb05e13X1SotaSS8hZJo+u9pUXhwrSnNbSoVZEBKC+dSqoksI6YHm89pUKA94eC++gJ1ul/HHMHrF49r1wvAKO7EUP0TBCtemyZYtVSrh0TmIkucyU9pUCzNB375Kmox8qbARrUXdlHjCkdisVqJMIZhEn34dfNah7Uc/lQj975ZR5k0zetyhnUHG7E/Blv1Nezo8rB2n4HxhTrKKLyRDXl3dtt2fDSr5UvzzZEBEiQ=="
+ },
+ {
+ "functionCall": {
+ "name": "multiply",
+ "args": {
+ "a": 2,
+ "b": 3
+ }
+ }
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0,
+ "finishMessage": "Model generated function call(s)."
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 161,
+ "candidatesTokenCount": 32,
+ "totalTokenCount": 289,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 161
+ }
+ ],
+ "thoughtsTokenCount": 96
+ },
+ "modelVersion": "gemini-3-pro-preview",
+ "responseId": "Z6IdadLwMIDXvdIPwbrDyAY"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 2.545695292s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1737
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"},{"parts":[{"functionCall":{"args":{"a":2,"b":3},"id":"1","name":"add"},"thoughtSignature":"Ep8DCpwDAdHtim9QdO0y9bZ65Rujicbol+wCUJKbtFVKI8R2aVL5g9KNn25HRk9RQTnn6Mf/bHwNDvm17S/NkwMNRHTnsrgsFhCnID3D3UUhs2a0PJAw2qr4I2JkLlDxSarHaYQL8FkzDJCyEfaKHa4wPEFCTQL4DYtVutBbO5/f8meUiUhZxBBuKshtXWlqO0ecRIKJ1UD+wMZ0BlFGdJGYoVVpYFlbk3/MJzmKzy21oDuzYLPSpHFi79QB6QucplXCYu37zxdYlzr6Hq5aGYf2Cw6qKr5j8F85I+zX5S0MPfVdK68nuPC4qb/qYGRUhMHzb05e13X1SotaSS8hZJo+u9pUXhwrSnNbSoVZEBKC+dSqoksI6YHm89pUKA94eC++gJ1ul/HHMHrF49r1wvAKO7EUP0TBCtemyZYtVSrh0TmIkucyU9pUCzNB375Kmox8qbARrUXdlHjCkdisVqJMIZhEn34dfNah7Uc/lQj975ZR5k0zetyhnUHG7E/Blv1Nezo8rB2n4HxhTrKKLyRDXl3dtt2fDSr5UvzzZEBEiQ=="},{"functionCall":{"args":{"a":2,"b":3},"id":"2","name":"multiply"}}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"add","response":{"result":"5"}}},{"functionResponse":{"id":"2","name":"multiply","response":{"result":"6"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "The sum of 2 and 3 is 5, and the product of 2 and 3 is 6."
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 309,
+ "candidatesTokenCount": 25,
+ "totalTokenCount": 334,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 309
+ }
+ ]
+ },
+ "modelVersion": "gemini-3-pro-preview",
+ "responseId": "aaIdadm_HNiCvdIPwrjEkAg"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.649148834s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/multi_tool_streaming.yaml
new file mode 100644
index 000000000..ee048e4fa
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/multi_tool_streaming.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 809
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. Always use both add and multiply at the same time."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"functionCall\": {\"name\": \"add\",\"args\": {\"b\": 3,\"a\": 2}},\"thoughtSignature\": \"ErwDCrkDAdHtim+tgyYiwTOKgDBZ5Psa/ivtDDfvnlqoGDEj97rV2/GvhSSnwedTysVM5tAb6zPepWfsdb2DQy7jdoiKr4XdeSCOUS5LrLlcfBYsfeYrCJv7eDxJMNRqh8yATI6m4HrsM8xmRv4r4T+ciSH6NVMBSRiTuq5+NbIlV1EYnedFeo6Bz76LYZhbeKg0bzOG+VsUQHmyzlevfzZGkJTcDNf16mnN6ncN3dnQEtKg3NCk2KB/zhAyXLRPxBCCYLgv70NKSPAmGhs8v4Qz3vRUCy8ikYN9XGTxPFyFepS/c1N9hWFeGOUerVCmLneXn/LaXHoD5d/w54Cz6EGetOskF9jdNnkZ9SDdAUCHmrcR69A84p/v+900Oxvt39e9KMvSTuar1K+XXuDX/ba6uQoi4ZStXZJKN/oCRmyKUKHUwsUs/1PAGIOgeizxETzC/ExIx4sVeQ7/aslTLP2Dt7842mwgP+TguCkpRmSccZGSqQ6lg+KMiDmqnfYf86Q5Vu5gjqm1o6Y9lRsgsec0ZW2l2+cCuIV1/jQxfSYI3L7lPRPkmmMCZJoXAYNLH1adCMil0Pfzl6rsRGc4\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 157,\"candidatesTokenCount\": 16,\"totalTokenCount\": 264,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 157}],\"thoughtsTokenCount\": 91},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"bKIdaeD9AuPUxs0Pk8v7uA0\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"functionCall\": {\"name\": \"multiply\",\"args\": {\"b\": 3,\"a\": 2}}}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 157,\"candidatesTokenCount\": 32,\"totalTokenCount\": 280,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 157}],\"thoughtsTokenCount\": 91},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"bKIdaeD9AuPUxs0Pk8v7uA0\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 157,\"candidatesTokenCount\": 32,\"totalTokenCount\": 280,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 157}],\"thoughtsTokenCount\": 91},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"bKIdaeD9AuPUxs0Pk8v7uA0\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.587839083s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1756
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"},{"parts":[{"functionCall":{"args":{"a":2,"b":3},"id":"1","name":"add"},"thoughtSignature":"ErwDCrkDAdHtim+tgyYiwTOKgDBZ5Psa/ivtDDfvnlqoGDEj97rV2/GvhSSnwedTysVM5tAb6zPepWfsdb2DQy7jdoiKr4XdeSCOUS5LrLlcfBYsfeYrCJv7eDxJMNRqh8yATI6m4HrsM8xmRv4r4T+ciSH6NVMBSRiTuq5+NbIlV1EYnedFeo6Bz76LYZhbeKg0bzOG+VsUQHmyzlevfzZGkJTcDNf16mnN6ncN3dnQEtKg3NCk2KB/zhAyXLRPxBCCYLgv70NKSPAmGhs8v4Qz3vRUCy8ikYN9XGTxPFyFepS/c1N9hWFeGOUerVCmLneXn/LaXHoD5d/w54Cz6EGetOskF9jdNnkZ9SDdAUCHmrcR69A84p/v+900Oxvt39e9KMvSTuar1K+XXuDX/ba6uQoi4ZStXZJKN/oCRmyKUKHUwsUs/1PAGIOgeizxETzC/ExIx4sVeQ7/aslTLP2Dt7842mwgP+TguCkpRmSccZGSqQ6lg+KMiDmqnfYf86Q5Vu5gjqm1o6Y9lRsgsec0ZW2l2+cCuIV1/jQxfSYI3L7lPRPkmmMCZJoXAYNLH1adCMil0Pfzl6rsRGc4"},{"functionCall":{"args":{"a":2,"b":3},"id":"2","name":"multiply"}}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"add","response":{"result":"5"}}},{"functionResponse":{"id":"2","name":"multiply","response":{"result":"6"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. Always use both add and multiply at the same time."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"The addition of \"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 211,\"candidatesTokenCount\": 4,\"totalTokenCount\": 215,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 211}]},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"baIdafSbGseSxN8P7IGBoAw\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"2 and 3 is 5, and the multiplication of 2 and \"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 211,\"candidatesTokenCount\": 20,\"totalTokenCount\": 231,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 211}]},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"baIdafSbGseSxN8P7IGBoAw\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"3 is 6.\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 211,\"candidatesTokenCount\": 25,\"totalTokenCount\": 236,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 211}]},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"baIdafSbGseSxN8P7IGBoAw\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 300,\"candidatesTokenCount\": 25,\"totalTokenCount\": 325,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 300}]},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"baIdafSbGseSxN8P7IGBoAw\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.385585417s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/simple.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/simple.yaml
new file mode 100644
index 000000000..f689e7f44
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/simple.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 202
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Say hi in Portuguese"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "You can say **\"Oi\"** or **\"OlĆ”\"**.",
+ "thoughtSignature": "Eu0GCuoGAdHtim/zutMjuEtbqFE0m3XHTgdm//ZDW7T5jsfXf8yWoYnJdjR3t52kdvNti1XtYOu1jAkcFlOJFxXFUtkO4rqxHjYAYNZuT6ONqFVaEmdfuYQYc6qk5qMRc24mbbUGM12zKY+JI1HMUV+Wa5YOtHNz96VFcRdI0DrZ7s8uSIrVV7CuV9+FkPRxfWq+tZ4gdqP5802+dBSwciDRAFLFCKCy8ZrpJIzcqmfGQPsbqiVBb3b8qtrlC2sSOHyHQklq+F9Jgkuka25MI2FSBah3IHaSYvtAz4YIXMbEoLVaRINy4+aPKjJvzwKAzva3EzNliJnb8N+fA2O/YdPDFqx2Mt+bb+2hl5buM6Xt7RO6RJ1fL1sSyVClETJGghUtIQd5mBON6Ts7Kpg468/wzU94Y/BMUSISITeZpipEG6BCM/cn7lhLK9DeWzGYRr5sYbUOMCBQhpbAVpzL0g9U4ySEhgTpR/+uVVYlPut77WYA/L9icnoBVf3+FovhSAKzx0C76p6Bp5SGR1abD5vb/2HeOTVaSWrJa9/tIYgiZNzZ777m9ymHUW1XCjjTPGGC97HaGA1jcwcryQ5FtG3IzaJjIIYpgKH6Fi3/yQlMS6xjFvb1ADoM3qz790L5HNUcX+9qfMpw91/aMDOGBTdaldH8poQkRLEB0kZwZ2yPdT2Y4RVaZCTn7MMtcGyp9gx7kuEiB3OfW2Sb6m3yC4n8fdGOfMoNUYeQsjavRpfQ+KzH+Fv9/QyTbMZKcVjfa1/dqJ8uRq9Oq/V6w7arhWLz5iJrtWMmDjwrwbNaOPCeUfBCINspvS+Q2qq5qu84lyd/3m7Bae/Uoz+VN2AlDwllUlMrd3cQ4e6Sp6Ibi+e7TPOF4xaOiCmPuLaqPEErZeNfzvAXQ6/ft8BGPOX835DQngZC70xgZnJqNSajVUl+i5P+hCxK58zFBPLswSCRaQHWd76hC3/Tv0CgsiuyNqfkpcLbT+C8E4TIkrbMsWEk3PZ4WAn/2+r/W3R+ox9pLYge+cx6/lz4oM4WKwCKHfipXmISKxqaTsVJaNJb/PIOdfEt+eVgxBzUill5exqksKQBn4wDDpy+TEQ1E5S1i+80XWumQBVlrDHIdYh3FROkK1n/P2GBS70sy9uScTKS8YJT2kfNcpuXQpnfHaoOpQ=="
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 11,
+ "candidatesTokenCount": 14,
+ "totalTokenCount": 243,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 11
+ }
+ ],
+ "thoughtsTokenCount": 218
+ },
+ "modelVersion": "gemini-3-pro-preview",
+ "responseId": "WKIdaZPHHfXzxs0Pn66hoAk"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 3.97765625s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/simple_streaming.yaml
new file mode 100644
index 000000000..dd97e0029
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/simple_streaming.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 202
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Say hi in Portuguese"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"}}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"You can say **\\\"Oi\\\"** or **\\\"OlĆ”\\\"**.\\n\\n* **Oi** is more informal (like \\\"Hi\\\").\\n* **OlĆ”** is slightly more formal (like \\\"Hello\\\").\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 11,\"candidatesTokenCount\": 43,\"totalTokenCount\": 361,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 11}],\"thoughtsTokenCount\": 307},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"XKIdabjbOtH3xN8P5NmBkQk\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"\",\"thoughtSignature\": \"ErkKCrYKAdHtim/DFrUx3uJvLE4jfIqzN3zSWBVxI1G7XuJBmEeNZJO64cM2d2681b4nCpBG1uTmz4sp1T2cNjZNYYav3OngCEWzmvzUbZz5WAYbuZPWdjZ9rn6v9xRynSfQ+kXScHJzG0XUTQzc+2OyG1haLUL62AEGBbFg04lbjPAOoUpTpDHk8BI9cW0dhbeDsdr7UFVvN8vpIA83xPQW/yuky2/J4pl70dIkFEhfJjaU2V/Ie7yRSup66ZDH5KdU+Dl5JQ43I8lPcqqoLXcDfNxUUzg/WuMzQ3PqvnbBpl9ScKNHJlEhg7909xrKrBtjX82r7vNgIaNL+k+DnWF3VowUaAS5g4g48gWfVcYECQCZXABr8UyDqC7eFn/z41eFbRI3DsiEQFozW2bdwQnkj4uZBZDyDWWN6bWgUZ9H5nyO4ah8B15UjMiy+rSrvciGdSfcF2uFUZ+IMh/bsWQrWHIudXyktiAv+/45864l8wmmSmmP/hvK6sC6C0c1xDVVCrX0EJYuTxhqR+s+p4XGXkUqn/FUp/MmImN+UJnM8zYuSKTQw1mCtODBGw3OEVvwXtWT50gG7tfz84S4VwCTlN2SjyvpniNpHDp/2qbrsXmpzywbnWsvRDiqcSj1NcHWeTgIf5zzcL6NyiSIjThhbl621mXJFXg1o2WBPXNE5JCAJ1dVAxpVoAz2FqMPGK4JEmgMDGzK0uHIHkZwHT+afM+H8ruurXQ9qCb7PNO0Js0kL2kbC/38Qoq3q2O0A320bTzeTwCpw7eJhSw5UPsxj1HBUgIiKmUgeC8lcsdqenVsF+WqxkUkpWWdDhIby0ejqZq7Yfn9I4C58AZwMKPsVt+2iHmTTv4VtZ13PFW/v2Khz04Eo5rkw/NZZ4FQUw4y+/9W4hoos5YDXpXKWugm6EfpRSr7KYw3nkVwJP/bIk+9Ex0xWau6cT9l7fwdvYEfDGJOKwH/AJzPNLAcOXhejG4s1FxSOoCesuLKsrQToFb2IWrM5eYL46hMDObTg60sHuFEMIrQu6CY2IYJ+eFtjydoKAMaPyF5evILUN8P6j6wURLakoEdIDq20UIIj6AFjLurOgauZNqHLiqmvlDr4rJubHhbGGYav43Rlpxql2rowEgsu+MSLGIan5VG+WNhAn2Z3ClFW8hqB7B/tTRAJAbgwM+MivX4wn2bua6erXVO8dihpWIVpjjNDhmUcweTHdb7h6M3Q80Gy9Yi+UPUJXWpoMq9TD/Hj4/wnDHKFChyTfGBohzQQa1onlGzg7kx2zHTBEj/9j06Po+OPpWHNpARP7RUEQKmMPkSfJLdsquumxM9w7uNypJ+KsADTfGT300tL3R6NMbQiPleQ8zREvXgq90tEhXP9kWOQJoXkeAtI4+9CuBlDUR8CxrQoz/ADVDYj46NLmGFObrDra7hCFpHgqSfi26ucScFKLFqnCYMaCj2/TbVLiXMnMPHvToiXzuKHPGn/FG/fYFagci8SraaYAUQjQGWenIlKf1zN6MlDJyZBr4QIw+Es0DdQOC7opu3Cdekila7XGENkJlr3tDXu30mjSJ29gPlM10aXwFIwapKpVe7mGMJBzyb64z8W+2ZOLOvBPQykWC55q+6NjLokqnZTh+2edxteBMfKC8IZV5OQgU9x573llLo6+ylCdgDCsZ68doHznPrrExj3zlw3yqvcBBLpVw+wiGRuAR6ZB4AEGMYCucbmJo82RnLQT4xK37zk2teE6sUoIPKEJa0cePMfaouAaRagmUJ+ylNPFFLT0N+B74=\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 11,\"candidatesTokenCount\": 43,\"totalTokenCount\": 361,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 11}],\"thoughtsTokenCount\": 307},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"XKIdabjbOtH3xN8P5NmBkQk\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 4.484338042s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/tool.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/tool.yaml
new file mode 100644
index 000000000..714bb2d98
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/tool.yaml
@@ -0,0 +1,127 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 509
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "functionCall": {
+ "name": "weather",
+ "args": {
+ "location": "Florence, Italy"
+ }
+ },
+ "thoughtSignature": "EvwCCvkCAdHtim+PQmLlXBFlyn5zkH9Ulj6upBtzURUlM9dI26vPsj3LG2Q4KeqoH5XyWdqCkF+ruALELNIQ27gg7Xp6EkWYYMBus01fmwUubUKhjIu0zV/3qpAfK44Zsg9QXONIVDKMwPJxDHd4XUIehDG0y1JICa9Om9hSdrcLcelx9wRMb79NsdBWO3JRwxAfaVlmtfnCdTRBfuQ1Vzs//ZxCQr9RHWnL9Z+ZXllJNvusWfUVEsyY288zIkOb4EJElnK7vto2gBY7vwlFsXg4JBjeBu9WLBu0Y3pQSZ35ktLDpO9W07OSDE57Id68JBtLxqb6XzxINYUdWTh2908VC6dnpEWSKN76uRq6G/5DVqUq5TGosYSvGsqRMLmEISxjy0g3j/foXQWeFMlLAG7Xn9sp0FHZraQ1AhlboTBW43uAJmJWmOLcti4JM/EQ0b1gc4heejJXRSjc6XOfvkczVBA4psJv4hgOXZvtoD5VwRD0WkOB5zMoo1MyqWI="
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0,
+ "finishMessage": "Model generated function call(s)."
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 65,
+ "candidatesTokenCount": 16,
+ "totalTokenCount": 148,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 65
+ }
+ ],
+ "thoughtsTokenCount": 67
+ },
+ "modelVersion": "gemini-3-pro-preview",
+ "responseId": "X6IdacDzD7jZvdIP6qu5mQk"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 2.275361292s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1257
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"location":"Florence, Italy"},"id":"1","name":"weather"},"thoughtSignature":"EvwCCvkCAdHtim+PQmLlXBFlyn5zkH9Ulj6upBtzURUlM9dI26vPsj3LG2Q4KeqoH5XyWdqCkF+ruALELNIQ27gg7Xp6EkWYYMBus01fmwUubUKhjIu0zV/3qpAfK44Zsg9QXONIVDKMwPJxDHd4XUIehDG0y1JICa9Om9hSdrcLcelx9wRMb79NsdBWO3JRwxAfaVlmtfnCdTRBfuQ1Vzs//ZxCQr9RHWnL9Z+ZXllJNvusWfUVEsyY288zIkOb4EJElnK7vto2gBY7vwlFsXg4JBjeBu9WLBu0Y3pQSZ35ktLDpO9W07OSDE57Id68JBtLxqb6XzxINYUdWTh2908VC6dnpEWSKN76uRq6G/5DVqUq5TGosYSvGsqRMLmEISxjy0g3j/foXQWeFMlLAG7Xn9sp0FHZraQ1AhlboTBW43uAJmJWmOLcti4JM/EQ0b1gc4heejJXRSjc6XOfvkczVBA4psJv4hgOXZvtoD5VwRD0WkOB5zMoo1MyqWI="}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"weather","response":{"result":"40 C"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "The weather in Florence, Italy is currently 40°C."
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 160,
+ "candidatesTokenCount": 14,
+ "totalTokenCount": 174,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 160
+ }
+ ]
+ },
+ "modelVersion": "gemini-3-pro-preview",
+ "responseId": "YKIdafKQMoC4vdIPquKD2Ak"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.575822583s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/tool_streaming.yaml
new file mode 100644
index 000000000..d792124c2
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/gemini-3-pro-preview/tool_streaming.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 509
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"functionCall\": {\"name\": \"weather\",\"args\": {\"location\": \"Florence, Italy\"}},\"thoughtSignature\": \"EpMECpAEAdHtim8rere5R73M3xFnVzAQ/SWKTJ6rbVa0wbXbF2KEW5iJtgQdfCxBJVRFzwaosCLNPuCRPFlCgwWM6UeGWtT+u6J+7uR4caEUrLLceIrVqOGnsis0sPowTQCatpjN0XMopVvu+o1eNXQUVl0EQmv5aGURtVQG8IRg4LhKFBXa/ZgNe7ODIMdTEYw/XDt/CaOpWsc1AJmbpj4sB0uSdk7d2BfKZUc8dbl8vduiq0LTLW0vWa5TUlgyAMLQqtjKU63YQsm4LHTizrlVNIOc7n0WBxdJkvmUzCoBtKhDkAsc2YQbjlq1PiLbQsL8I1gd6zXe0AZyXq/4ZviOsmE0pzeMgYmjqLE3fuvsQctWIrDzZoNZzydYD/PAXC12GH6W0SJd9Cqo7oia9f+sSHejvWog3ztheMh0Ut60PYSCSkytq6R26Utt9RLp4xZ1gwSjOVY4dX8eEnAYu03Q/OVsVbmRM6po5los4V+ir07w7fvi5X5LoKrO7vNx+SdQDaty0UzWmw8DxET82S/nPgXOQg6nj2VHUJyGICBhwAJjMMOanLPvcS53gNfkkW0znGXjCuyTGBuhN+ngAE/SZKr6kNP1Eq2cGMECe5YyPktrcnskV8ey6Q+OLa0fvVqWhCyqYP11D173JRgqnTvKLCkO6GXM3R2kcOP/nCDqalYfpWLUpeuyRnGaggM2My6NrR84\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 65,\"candidatesTokenCount\": 16,\"totalTokenCount\": 176,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 65}],\"thoughtsTokenCount\": 95},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"Y6IdafqZF-3Zxs0PsZuluAk\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 65,\"candidatesTokenCount\": 16,\"totalTokenCount\": 176,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 65}],\"thoughtsTokenCount\": 95},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"Y6IdafqZF-3Zxs0PsZuluAk\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.580842917s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1457
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"location":"Florence, Italy"},"id":"1","name":"weather"},"thoughtSignature":"EpMECpAEAdHtim8rere5R73M3xFnVzAQ/SWKTJ6rbVa0wbXbF2KEW5iJtgQdfCxBJVRFzwaosCLNPuCRPFlCgwWM6UeGWtT+u6J+7uR4caEUrLLceIrVqOGnsis0sPowTQCatpjN0XMopVvu+o1eNXQUVl0EQmv5aGURtVQG8IRg4LhKFBXa/ZgNe7ODIMdTEYw/XDt/CaOpWsc1AJmbpj4sB0uSdk7d2BfKZUc8dbl8vduiq0LTLW0vWa5TUlgyAMLQqtjKU63YQsm4LHTizrlVNIOc7n0WBxdJkvmUzCoBtKhDkAsc2YQbjlq1PiLbQsL8I1gd6zXe0AZyXq/4ZviOsmE0pzeMgYmjqLE3fuvsQctWIrDzZoNZzydYD/PAXC12GH6W0SJd9Cqo7oia9f+sSHejvWog3ztheMh0Ut60PYSCSkytq6R26Utt9RLp4xZ1gwSjOVY4dX8eEnAYu03Q/OVsVbmRM6po5los4V+ir07w7fvi5X5LoKrO7vNx+SdQDaty0UzWmw8DxET82S/nPgXOQg6nj2VHUJyGICBhwAJjMMOanLPvcS53gNfkkW0znGXjCuyTGBuhN+ngAE/SZKr6kNP1Eq2cGMECe5YyPktrcnskV8ey6Q+OLa0fvVqWhCyqYP11D173JRgqnTvKLCkO6GXM3R2kcOP/nCDqalYfpWLUpeuyRnGaggM2My6NrR84"}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"weather","response":{"result":"40 C"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"The\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 95,\"candidatesTokenCount\": 1,\"totalTokenCount\": 96,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 95}]},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"ZaIdaeuyDKuP28oPu5_O2Q4\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \" weather in Florence, Italy is currently 40 degrees Celsius.\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 95,\"candidatesTokenCount\": 14,\"totalTokenCount\": 109,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 95}]},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"ZaIdaeuyDKuP28oPu5_O2Q4\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 188,\"candidatesTokenCount\": 14,\"totalTokenCount\": 202,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 188}]},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"ZaIdaeuyDKuP28oPu5_O2Q4\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.789773542s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-claude-3-7-sonnet/simple.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-claude-3-7-sonnet/simple.yaml
new file mode 100644
index 000000000..dc1cf23ec
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-claude-3-7-sonnet/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 210
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Say hi in Portuguese","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"anthropic_version":"vertex-2023-10-16"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://us-east5-aiplatform.googleapis.com/v1/projects/fantasy-playground-472418/locations/us-east5/publishers/anthropic/models/claude-3-7-sonnet@20250219:rawPredict
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_vrtx_011D8f9pw4KabWttPrkbaAL6","type":"message","role":"assistant","content":[{"type":"text","text":"OlĆ”! Como posso ajudar vocĆŖ hoje?"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":16,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":16}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.980568375s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-claude-3-7-sonnet/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-claude-3-7-sonnet/simple_streaming.yaml
new file mode 100644
index 000000000..870d04c89
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-claude-3-7-sonnet/simple_streaming.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 224
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Say hi in Portuguese","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"stream":true,"anthropic_version":"vertex-2023-10-16"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://us-east5-aiplatform.googleapis.com/v1/projects/fantasy-playground-472418/locations/us-east5/publishers/anthropic/models/claude-3-7-sonnet@20250219:streamRawPredict
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"model":"claude-3-7-sonnet-20250219","id":"msg_vrtx_013va9SBUhdmyiMNdWQdAJXr","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":16,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":5}} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"OlĆ”! Como"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" pos"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"so aju"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"dar vocĆŖ hoje?"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":16} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.261146292s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-claude-3-7-sonnet/tool.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-claude-3-7-sonnet/tool.yaml
new file mode 100644
index 000000000..dc98cb0ab
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-claude-3-7-sonnet/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 501
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"anthropic_version":"vertex-2023-10-16"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://us-east5-aiplatform.googleapis.com/v1/projects/fantasy-playground-472418/locations/us-east5/publishers/anthropic/models/claude-3-7-sonnet@20250219:rawPredict
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_vrtx_018rHJHvE1H6hfLm167nmkRj","type":"message","role":"assistant","content":[{"type":"text","text":"I''ll check the current weather in Florence, Italy for you."},{"type":"tool_use","id":"toolu_vrtx_01EKDu37P36gfuCEwCpy6fer","name":"weather","input":{"location":"Florence,Italy"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":394,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":67}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.085536084s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 881
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"},{"content":[{"text":"I''ll check the current weather in Florence, Italy for you.","type":"text"},{"id":"toolu_vrtx_01EKDu37P36gfuCEwCpy6fer","input":{"location":"Florence,Italy"},"name":"weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_vrtx_01EKDu37P36gfuCEwCpy6fer","content":[{"text":"40 C","type":"text"}],"type":"tool_result"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"anthropic_version":"vertex-2023-10-16"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://us-east5-aiplatform.googleapis.com/v1/projects/fantasy-playground-472418/locations/us-east5/publishers/anthropic/models/claude-3-7-sonnet@20250219:rawPredict
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_vrtx_014QWCD9SGFBuL4dWvcDrX48","type":"message","role":"assistant","content":[{"type":"text","text":"The current temperature in Florence, Italy is 40°C (104°F), which is very hot. Make sure to stay hydrated and try to avoid prolonged exposure to the sun if you''re there or planning to visit soon."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":475,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":52}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.480864125s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-claude-3-7-sonnet/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-claude-3-7-sonnet/tool_streaming.yaml
new file mode 100644
index 000000000..f74bc76b6
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-claude-3-7-sonnet/tool_streaming.yaml
@@ -0,0 +1,180 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 515
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"stream":true,"anthropic_version":"vertex-2023-10-16"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://us-east5-aiplatform.googleapis.com/v1/projects/fantasy-playground-472418/locations/us-east5/publishers/anthropic/models/claude-3-7-sonnet@20250219:streamRawPredict
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"model":"claude-3-7-sonnet-20250219","id":"msg_vrtx_01BskFKCoRmtNwwLEZceS2hN","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":394,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":2}} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"I'll"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" get the"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" weather"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" information for Florence, Italy"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" for you."} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0}
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_vrtx_01Ko1dsGPQQd4y3nsTPLMQcM","name":"weather","input":{}}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"lo"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"cation\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":": \"Floren"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"ce,Italy"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\"}"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":1 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"output_tokens":67} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 752.193583ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 898
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"What''s the weather in Florence,Italy?","type":"text"}],"role":"user"},{"content":[{"text":"I''ll get the weather information for Florence, Italy for you.","type":"text"},{"id":"toolu_vrtx_01Ko1dsGPQQd4y3nsTPLMQcM","input":{"location":"Florence,Italy"},"name":"weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_vrtx_01Ko1dsGPQQd4y3nsTPLMQcM","content":[{"text":"40 C","type":"text"}],"type":"tool_result"}],"role":"user"}],"system":[{"text":"You are a helpful assistant","type":"text"}],"tool_choice":{"disable_parallel_tool_use":false,"type":"auto"},"tools":[{"input_schema":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location"}],"stream":true,"anthropic_version":"vertex-2023-10-16"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://us-east5-aiplatform.googleapis.com/v1/projects/fantasy-playground-472418/locations/us-east5/publishers/anthropic/models/claude-3-7-sonnet@20250219:streamRawPredict
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"model":"claude-3-7-sonnet-20250219","id":"msg_vrtx_01Lnb15G6n5yup7eiSG1MJP3","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":475,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":2}} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"It"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"'s currently 40 "} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"degrees Celsius in Florence"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":", Italy."} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" That"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"'s quite"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" hot"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"! Make"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" sure to stay"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" hydrated and try"}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" to avoid being"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" outside during the peak"}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" heat of the day if"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" possible."} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":45} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.308048041s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/multi_tool.yaml
new file mode 100644
index 000000000..2391bc40e
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/multi_tool.yaml
@@ -0,0 +1,152 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 826
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "role": "model",
+ "parts": [
+ {
+ "functionCall": {
+ "name": "add",
+ "args": {
+ "a": 2,
+ "b": 3
+ }
+ },
+ "thoughtSignature": "CtQBAePx/16Zez8Umc39OZNkaQcoaJ1i+yLTUes4eYNcobNd2vH2Jza1Q9tqpUP3e9MCA7Az0IRM9hVbj63fFwx8AT9u4FhaQRdazvEkYMqe+jGLiO6yex245G4qobHLIydnzgPJA6OMCVsuxxjHM1QhmT31E5Qg/ZVeh6Fc6ZI3S+q3TC1+tNxGr2EBlWfWyfHIOtr2qsGfZSSVOaB9Wj1jY/alOSKrSFC0PiCGhvmMwnawJWlzYkshIfAssUetPp+bDW5grOJoKWATcF3kTFShItAs6Xc="
+ },
+ {
+ "functionCall": {
+ "name": "multiply",
+ "args": {
+ "a": 2,
+ "b": 3
+ }
+ }
+ }
+ ]
+ },
+ "finishReason": "STOP",
+ "avgLogprobs": -0.58420848846435547
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 60,
+ "candidatesTokenCount": 10,
+ "totalTokenCount": 119,
+ "trafficType": "ON_DEMAND",
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 60
+ }
+ ],
+ "candidatesTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 10
+ }
+ ],
+ "thoughtsTokenCount": 49
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "createTime": "2025-11-19T11:04:06.032691Z",
+ "responseId": "JqQdabP_AfrJptQP15PtmQI"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 989.592584ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1465
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"},{"parts":[{"functionCall":{"args":{"a":2,"b":3},"id":"1","name":"add"},"thoughtSignature":"CtQBAePx/16Zez8Umc39OZNkaQcoaJ1i+yLTUes4eYNcobNd2vH2Jza1Q9tqpUP3e9MCA7Az0IRM9hVbj63fFwx8AT9u4FhaQRdazvEkYMqe+jGLiO6yex245G4qobHLIydnzgPJA6OMCVsuxxjHM1QhmT31E5Qg/ZVeh6Fc6ZI3S+q3TC1+tNxGr2EBlWfWyfHIOtr2qsGfZSSVOaB9Wj1jY/alOSKrSFC0PiCGhvmMwnawJWlzYkshIfAssUetPp+bDW5grOJoKWATcF3kTFShItAs6Xc="},{"functionCall":{"args":{"a":2,"b":3},"id":"2","name":"multiply"}}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"add","response":{"result":"5"}}},{"functionResponse":{"id":"2","name":"multiply","response":{"result":"6"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "role": "model",
+ "parts": [
+ {
+ "text": "The sum of 2 and 3 is 5. The product of 2 and 3 is 6."
+ }
+ ]
+ },
+ "finishReason": "STOP",
+ "avgLogprobs": -0.038081047435601555
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 76,
+ "candidatesTokenCount": 24,
+ "totalTokenCount": 100,
+ "trafficType": "ON_DEMAND",
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 123
+ }
+ ],
+ "candidatesTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 24
+ }
+ ]
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "createTime": "2025-11-19T11:04:07.021113Z",
+ "responseId": "J6QdafmkAeyAptQPvKrv8AI"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 679.733ms
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/multi_tool_streaming.yaml
new file mode 100644
index 000000000..c4251a4ef
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/multi_tool_streaming.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 809
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. Always use both add and multiply at the same time."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-flash:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"functionCall\": {\"name\": \"add\",\"args\": {\"a\": 2,\"b\": 3}},\"thoughtSignature\": \"Ci8B4/H/XsVjmQllPB1vwXsit6Cy6bO83UTy/g2xrDRI+kS+lSc5zTqIPp2WuV1dFAphAePx/1778NrXCSJC9DjysS5FDbk2qa2fdkpGT8AKSg3Gb9z6oBbS7lqKRfgAiqvPKXwwxLplcnnJ3Eez3UYC+2NI+JSeeBqOhxEmH6qbFXdcQPyf7IY1BCdynZ37b4wNJApdAePx/1455hKMzvD1Dy3HayN6NX2qyXtP3OC+vwWXrjyA8J8U2TBMgsE2Rer1TmJDLu+LX2o2BX/ECsnXAIOV5CxYGbXhA0pa5PENJvWpKlKDNZhRHLDMFw4f+WZVCqUBAePx/17pAvxLAWqaxXNGe5Z1qiN/FPaqRhvnG4IAVlYbM8yniWCY1P6DLIMBQ7ocubcSFRDMaYW7Oh5/WVwBTQ9wq2Yyg2YaAjdi3h8Si8ujsXbxzSKMqHjYrhEfWmT9nxSnsyztHsPCnLL9SlnBxURfWaNJXG7r6cgf3r/tyRJ5X1ar/iH3dkjp58MubpJJaMx+H022YAPMnWmIvJ4J4vsrwoDJ\"},{\"functionCall\": {\"name\": \"multiply\",\"args\": {\"a\": 2,\"b\": 3}}}]},\"finishReason\": \"STOP\"}],\"usageMetadata\": {\"promptTokenCount\": 57,\"candidatesTokenCount\": 10,\"totalTokenCount\": 147,\"trafficType\": \"ON_DEMAND\",\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 57}],\"candidatesTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 10}],\"thoughtsTokenCount\": 80},\"modelVersion\": \"gemini-2.5-flash\",\"createTime\": \"2025-11-19T11:04:07.904252Z\",\"responseId\": \"J6QdabyYN4qb5OMPr6PXcQ\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.012000667s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1708
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"},{"parts":[{"functionCall":{"args":{"a":2,"b":3},"id":"1","name":"add"},"thoughtSignature":"Ci8B4/H/XsVjmQllPB1vwXsit6Cy6bO83UTy/g2xrDRI+kS+lSc5zTqIPp2WuV1dFAphAePx/1778NrXCSJC9DjysS5FDbk2qa2fdkpGT8AKSg3Gb9z6oBbS7lqKRfgAiqvPKXwwxLplcnnJ3Eez3UYC+2NI+JSeeBqOhxEmH6qbFXdcQPyf7IY1BCdynZ37b4wNJApdAePx/1455hKMzvD1Dy3HayN6NX2qyXtP3OC+vwWXrjyA8J8U2TBMgsE2Rer1TmJDLu+LX2o2BX/ECsnXAIOV5CxYGbXhA0pa5PENJvWpKlKDNZhRHLDMFw4f+WZVCqUBAePx/17pAvxLAWqaxXNGe5Z1qiN/FPaqRhvnG4IAVlYbM8yniWCY1P6DLIMBQ7ocubcSFRDMaYW7Oh5/WVwBTQ9wq2Yyg2YaAjdi3h8Si8ujsXbxzSKMqHjYrhEfWmT9nxSnsyztHsPCnLL9SlnBxURfWaNJXG7r6cgf3r/tyRJ5X1ar/iH3dkjp58MubpJJaMx+H022YAPMnWmIvJ4J4vsrwoDJ"},{"functionCall":{"args":{"a":2,"b":3},"id":"2","name":"multiply"}}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"add","response":{"result":"5"}}},{"functionResponse":{"id":"2","name":"multiply","response":{"result":"6"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. Always use both add and multiply at the same time."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-flash:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \"The sum of 2 and\"}]}}],\"usageMetadata\": {\"trafficType\": \"ON_DEMAND\"},\"modelVersion\": \"gemini-2.5-flash\",\"createTime\": \"2025-11-19T11:04:08.930164Z\",\"responseId\": \"KKQdafTiOKnzptQPke-o4AE\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \" 3 is 5. The product of 2 and 3 is 6.\"}]},\"finishReason\": \"STOP\"}],\"usageMetadata\": {\"promptTokenCount\": 151,\"candidatesTokenCount\": 24,\"totalTokenCount\": 175,\"trafficType\": \"ON_DEMAND\",\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 151}],\"candidatesTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 24}]},\"modelVersion\": \"gemini-2.5-flash\",\"createTime\": \"2025-11-19T11:04:08.930164Z\",\"responseId\": \"KKQdafTiOKnzptQPke-o4AE\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 550.507042ms
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/simple.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/simple.yaml
new file mode 100644
index 000000000..b3d6e8501
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/simple.yaml
@@ -0,0 +1,70 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 202
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Say hi in Portuguese"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "role": "model",
+ "parts": [
+ {
+ "text": "OlĆ”!"
+ }
+ ]
+ },
+ "finishReason": "STOP",
+ "avgLogprobs": -0.58062881231307983
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 9,
+ "candidatesTokenCount": 2,
+ "totalTokenCount": 37,
+ "trafficType": "ON_DEMAND",
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 9
+ }
+ ],
+ "candidatesTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 2
+ }
+ ],
+ "thoughtsTokenCount": 26
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "createTime": "2025-11-19T11:04:00.570529Z",
+ "responseId": "IKQdaaHpIuyAptQPvKrv8AI"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.624110084s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/simple_streaming.yaml
new file mode 100644
index 000000000..d4b10d18f
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/simple_streaming.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 202
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Say hi in Portuguese"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"}}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-flash:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \"OlĆ”!\"}]},\"finishReason\": \"STOP\"}],\"usageMetadata\": {\"promptTokenCount\": 9,\"candidatesTokenCount\": 2,\"totalTokenCount\": 37,\"trafficType\": \"ON_DEMAND\",\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 9}],\"candidatesTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 2}],\"thoughtsTokenCount\": 26},\"modelVersion\": \"gemini-2.5-flash\",\"createTime\": \"2025-11-19T11:04:01.771732Z\",\"responseId\": \"IaQdaZSNL_rJptQP15PtmQI\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 725.084625ms
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/tool.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/tool.yaml
new file mode 100644
index 000000000..961e84b47
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/tool.yaml
@@ -0,0 +1,142 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 509
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "role": "model",
+ "parts": [
+ {
+ "functionCall": {
+ "name": "weather",
+ "args": {
+ "location": "Florence,Italy"
+ }
+ },
+ "thoughtSignature": "Cq4CAePx/17lfvNzeD1UgoF8F6LxiSlPe5DfakwGl5buoL2pFazz+R2IYIE4Z5S71KgiO9VbYj/6bJK5FBJm21GoJref0w1PDVF+/93xJylQhMB6ID/QCMDzRQfucel2hkwuhQscItWpTbvh5+/0NGY3Uo/bO5F4FLgrwmCRfqXl3EIkavxBOfk8Z4/H7SCd7/fYFvvTgCu+7ycBYyLYhvzYyGxTH7Ups0SWNaYueSPusvRa3FG8Y4BQKENgTWVlReJyuCHjyFHSxCtuDL8xEGaBE24ltsiN6qXw5F4uZyZndKskWLtdedDAjxOW/2bAwb5l9UZhfSmBDV4mHEz8JeMoejbUdSnBZk+hoahL6NhTLyEB6tHsnFqHC5bI4FOJmCgH6LsguTmD2Fmjf+QE5yw="
+ }
+ ]
+ },
+ "finishReason": "STOP",
+ "avgLogprobs": -1.5359557151794434
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 28,
+ "candidatesTokenCount": 5,
+ "totalTokenCount": 95,
+ "trafficType": "ON_DEMAND",
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 28
+ }
+ ],
+ "candidatesTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 5
+ }
+ ],
+ "thoughtsTokenCount": 62
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "createTime": "2025-11-19T11:04:02.601478Z",
+ "responseId": "IqQdaYbbJNmDptQP7qyZuAE"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 882.023417ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1152
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"location":"Florence,Italy"},"id":"1","name":"weather"},"thoughtSignature":"Cq4CAePx/17lfvNzeD1UgoF8F6LxiSlPe5DfakwGl5buoL2pFazz+R2IYIE4Z5S71KgiO9VbYj/6bJK5FBJm21GoJref0w1PDVF+/93xJylQhMB6ID/QCMDzRQfucel2hkwuhQscItWpTbvh5+/0NGY3Uo/bO5F4FLgrwmCRfqXl3EIkavxBOfk8Z4/H7SCd7/fYFvvTgCu+7ycBYyLYhvzYyGxTH7Ups0SWNaYueSPusvRa3FG8Y4BQKENgTWVlReJyuCHjyFHSxCtuDL8xEGaBE24ltsiN6qXw5F4uZyZndKskWLtdedDAjxOW/2bAwb5l9UZhfSmBDV4mHEz8JeMoejbUdSnBZk+hoahL6NhTLyEB6tHsnFqHC5bI4FOJmCgH6LsguTmD2Fmjf+QE5yw="}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"weather","response":{"result":"40 C"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "role": "model",
+ "parts": [
+ {
+ "text": "The weather in Florence, Italy is 40 C."
+ }
+ ]
+ },
+ "finishReason": "STOP",
+ "avgLogprobs": -0.027842623492081959
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 38,
+ "candidatesTokenCount": 12,
+ "totalTokenCount": 50,
+ "trafficType": "ON_DEMAND",
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 98
+ }
+ ],
+ "candidatesTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 12
+ }
+ ]
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "createTime": "2025-11-19T11:04:03.494403Z",
+ "responseId": "I6QdacOWHqrL5OMPtpzzmA8"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 540.870084ms
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/tool_streaming.yaml
new file mode 100644
index 000000000..4956ca650
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-flash/tool_streaming.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 509
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-flash:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"functionCall\": {\"name\": \"weather\",\"args\": {\"location\": \"Florence, Italy\"}},\"thoughtSignature\": \"CiwB4/H/XgPBx7H41mQWWTneSxzTQCyc0wzScVKc5AIn3b8TgdZFbTC1d2qUdgptAePx/15mCGBnWhulJd1gjHhny9mo+yzbH7tj5jIXAk1vLBp/plv9Qndwx+68CtQ3eZQa82W27zN7rJWw8Q5FW3NDGOiyXnfKXLOGKQ1x5+iF6wqe1Ec/nGhHEwB9t7NlhMWdtibPkELCfMhomgp6AePx/1608eQCMND2Pl/a47/lzL/nrECGx9ZAjsU+/4UHzTGH6vxQRmwNDZYqhrBcSxC2VA/ocT1F3eP6wMj8xDTWBHddDiA6WimCaXKT+aGRbnIXQfjhtOadLyNcCtea/7ny7CvrmsrTjJ4BfjToI87NtfObamCGJgIKVAHj8f9e2NadgSaLliJnkuWSr5p9PHqLP9pI0Fos4xq1pTJU3X4ar6fcLqymxxXfqgFmrcIWRkDiDG0N8LDtk1hsA4kZThlWIEvrGiLYFpx+HCqTTw==\"}]},\"finishReason\": \"STOP\"}],\"usageMetadata\": {\"promptTokenCount\": 28,\"candidatesTokenCount\": 5,\"totalTokenCount\": 86,\"trafficType\": \"ON_DEMAND\",\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 28}],\"candidatesTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 5}],\"thoughtsTokenCount\": 53},\"modelVersion\": \"gemini-2.5-flash\",\"createTime\": \"2025-11-19T11:04:04.229621Z\",\"responseId\": \"JKQdafWBDrrIptQPxeKNkA4\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 945.3105ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1237
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"location":"Florence, Italy"},"id":"1","name":"weather"},"thoughtSignature":"CiwB4/H/XgPBx7H41mQWWTneSxzTQCyc0wzScVKc5AIn3b8TgdZFbTC1d2qUdgptAePx/15mCGBnWhulJd1gjHhny9mo+yzbH7tj5jIXAk1vLBp/plv9Qndwx+68CtQ3eZQa82W27zN7rJWw8Q5FW3NDGOiyXnfKXLOGKQ1x5+iF6wqe1Ec/nGhHEwB9t7NlhMWdtibPkELCfMhomgp6AePx/1608eQCMND2Pl/a47/lzL/nrECGx9ZAjsU+/4UHzTGH6vxQRmwNDZYqhrBcSxC2VA/ocT1F3eP6wMj8xDTWBHddDiA6WimCaXKT+aGRbnIXQfjhtOadLyNcCtea/7ny7CvrmsrTjJ4BfjToI87NtfObamCGJgIKVAHj8f9e2NadgSaLliJnkuWSr5p9PHqLP9pI0Fos4xq1pTJU3X4ar6fcLqymxxXfqgFmrcIWRkDiDG0N8LDtk1hsA4kZThlWIEvrGiLYFpx+HCqTTw=="}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"weather","response":{"result":"40 C"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-flash:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \"The weather in Florence, Italy\"}]}}],\"usageMetadata\": {\"trafficType\": \"ON_DEMAND\"},\"modelVersion\": \"gemini-2.5-flash\",\"createTime\": \"2025-11-19T11:04:05.175922Z\",\"responseId\": \"JaQdabLeCoqb5OMPr6PXcQ\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \" is 40 C.\"}]},\"finishReason\": \"STOP\"}],\"usageMetadata\": {\"promptTokenCount\": 89,\"candidatesTokenCount\": 12,\"totalTokenCount\": 101,\"trafficType\": \"ON_DEMAND\",\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 89}],\"candidatesTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 12}]},\"modelVersion\": \"gemini-2.5-flash\",\"createTime\": \"2025-11-19T11:04:05.175922Z\",\"responseId\": \"JaQdabLeCoqb5OMPr6PXcQ\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 520.063542ms
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/multi_tool.yaml
new file mode 100644
index 000000000..c05e87a09
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/multi_tool.yaml
@@ -0,0 +1,152 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 826
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "role": "model",
+ "parts": [
+ {
+ "functionCall": {
+ "name": "add",
+ "args": {
+ "b": 3,
+ "a": 2
+ }
+ },
+ "thoughtSignature": "CukEAePx/15QJY0aW7MHjQUB+ypu3XOoG34numgtrxgqkyaR0fEZ6GidH4rlWetcv9trdN9jcp+uPvzLT6T24tPBx5XFJdZJn1ZtouXhZhcPHqTcl4a10cV5aL21bSWLls81NkGLTKqs1cAvaERIxIBcgAnw+IyilHbLMii3/axH5VzzpKkfcutk7k/1E0en0cp4HxV49f1jIGA3UrUWTEd4F9ntyCONE4gwOZSAmGJj/ZQv/O4dM2cWehyIgzGhlZ/Wg6cd9kQHU1FCgWBRSgAWmMKhq81PdeXwOBqPC25fyGjba2jRUN9+o1LalYwTK19XDy62YIaNa3XBkouKTyLisalJG7rs6Ch/5oBGWkOCgrIumkAFV1dkqiFpFEcZO++RLblx3yaTIltm0RAD2cohnwXe80RXek7V6Z07fIT9C7SLcFPyl9NIYTnWzT1AI0YLj3J7BK1BFzjRpVsuXE7tWp0uRzVdR2Up/iZYoMuFKJEDx3oqOBlEMFlKytCWU8+c9NgRKEkOlDzyf033XU0kth6YNlXab08xkxwPSVQps+pqyuIYaGvtZncB6lpnGznQ/x5x33Td6/0xgLH2A+QVNME/GVIEXIGOHvVQ09WTKRYAYLxWFY3U+ybXUh5gLaTa2bEuF588YQUL0fIka8KiMUbBvRi78QRWAEQNks/Z/zFNhmMzseiOSfAuhBZ3rlGsvSc676kIWziYC/kq710p5DQP0jTFbPV1InSnqToaXFY766vK6yjZJ8FVHlqRM+YK6g5pxpmJu05TS1V1xYCu+g2o7lQVtCZI1O0ELqnZkU8ESk2kxtw8qrU="
+ },
+ {
+ "functionCall": {
+ "name": "multiply",
+ "args": {
+ "a": 2,
+ "b": 3
+ }
+ }
+ }
+ ]
+ },
+ "finishReason": "STOP",
+ "avgLogprobs": -1.2367894172668457
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 60,
+ "candidatesTokenCount": 10,
+ "totalTokenCount": 241,
+ "trafficType": "ON_DEMAND",
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 60
+ }
+ ],
+ "candidatesTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 10
+ }
+ ],
+ "thoughtsTokenCount": 171
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "createTime": "2025-11-19T11:04:37.627146Z",
+ "responseId": "RaQdacqjJrCI0ekP8tCGkAk"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 3.051268875s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2005
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"},{"parts":[{"functionCall":{"args":{"a":2,"b":3},"id":"1","name":"add"},"thoughtSignature":"CukEAePx/15QJY0aW7MHjQUB+ypu3XOoG34numgtrxgqkyaR0fEZ6GidH4rlWetcv9trdN9jcp+uPvzLT6T24tPBx5XFJdZJn1ZtouXhZhcPHqTcl4a10cV5aL21bSWLls81NkGLTKqs1cAvaERIxIBcgAnw+IyilHbLMii3/axH5VzzpKkfcutk7k/1E0en0cp4HxV49f1jIGA3UrUWTEd4F9ntyCONE4gwOZSAmGJj/ZQv/O4dM2cWehyIgzGhlZ/Wg6cd9kQHU1FCgWBRSgAWmMKhq81PdeXwOBqPC25fyGjba2jRUN9+o1LalYwTK19XDy62YIaNa3XBkouKTyLisalJG7rs6Ch/5oBGWkOCgrIumkAFV1dkqiFpFEcZO++RLblx3yaTIltm0RAD2cohnwXe80RXek7V6Z07fIT9C7SLcFPyl9NIYTnWzT1AI0YLj3J7BK1BFzjRpVsuXE7tWp0uRzVdR2Up/iZYoMuFKJEDx3oqOBlEMFlKytCWU8+c9NgRKEkOlDzyf033XU0kth6YNlXab08xkxwPSVQps+pqyuIYaGvtZncB6lpnGznQ/x5x33Td6/0xgLH2A+QVNME/GVIEXIGOHvVQ09WTKRYAYLxWFY3U+ybXUh5gLaTa2bEuF588YQUL0fIka8KiMUbBvRi78QRWAEQNks/Z/zFNhmMzseiOSfAuhBZ3rlGsvSc676kIWziYC/kq710p5DQP0jTFbPV1InSnqToaXFY766vK6yjZJ8FVHlqRM+YK6g5pxpmJu05TS1V1xYCu+g2o7lQVtCZI1O0ELqnZkU8ESk2kxtw8qrU="},{"functionCall":{"args":{"a":2,"b":3},"id":"2","name":"multiply"}}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"add","response":{"result":"5"}}},{"functionResponse":{"id":"2","name":"multiply","response":{"result":"6"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "role": "model",
+ "parts": [
+ {
+ "text": "OK. The sum is 5 and the product is 6.\n"
+ }
+ ]
+ },
+ "finishReason": "STOP",
+ "avgLogprobs": -0.17488816579182942
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 76,
+ "candidatesTokenCount": 15,
+ "totalTokenCount": 91,
+ "trafficType": "ON_DEMAND",
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 245
+ }
+ ],
+ "candidatesTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 15
+ }
+ ]
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "createTime": "2025-11-19T11:04:40.692907Z",
+ "responseId": "SKQdaaulKqWO0ekPgvO5sQY"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.02390475s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/multi_tool_streaming.yaml
new file mode 100644
index 000000000..0c4f0b292
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/multi_tool_streaming.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 809
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. Always use both add and multiply at the same time."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"functionCall\": {\"name\": \"add\",\"args\": {\"a\": 2,\"b\": 3}},\"thoughtSignature\": \"CjYB4/H/XqxbQHp2lO9C6z3WWzvVvCiyYUrbBx1L6sQ7hZMExUrufaOgtboKjNVDxYTfY4AsVGcKagHj8f9e1baijGdlfKMfiyGh7mqF3XxfqA9oBZ0mq80e35Kg/CFJiNoFvmmg5vzmSNFq+VLsp92Hw1SCypKySEiF01T0znZgyHN0XwoHeKXAgKk1zFd/Mh9qSsLSC/TPC4vMzjL0qu8Y9RwKZwHj8f9e76FXbccQAPVDxI0QWNsv8dAlgeOaMF1nWU5bouU3cBMwhHFlxz3vz6Ke7XSUiaRYCKz02ZkAd+nxIhHQCCdsl+UUxeybFhfcnmXkIt+zCNFE6SN27CGNDksDumieTr1ZuwIKmgEB4/H/XirqiC8E/xdsBnuN9R4FskbNkWDsLZEenVvz5z3xEAYNGZQpWrw11Wbh/djAiI+HLKgR7VNL7wIbCLO9Jp49wXmNYQg07zeT08rxomsPAHzQAx2TbhoYlMyQSgh/P2aV9yQyGoqaed6NWw0LcKH6RADevMvjfsSxSqb7XHDd7FsSlz+khkGU+gAPSc/rWKBIIz5HakAkCqYBAePx/14T3qNkdp51GdNccS6BIdTKyfkJyjEzghaYr/+sX9aMa2nEpZRrkFj2j6lhorejLvuTBzKDiFQzebD+cTO6ajefAsMsvlO/4+QQ6oF/DviC/T/DIV5N2sf4FbC2qdiR+rfeplH3OYy3XYVlVhjlDc/ruvla0lMhRjlSHscPCCI4mBzaMRlgfWC3rGlrat2Mvw/Vpfg8U5t0vyxsS/mu+BWgzQ==\"},{\"functionCall\": {\"name\": \"multiply\",\"args\": {\"b\": 3,\"a\": 2}}}]},\"finishReason\": \"STOP\"}],\"usageMetadata\": {\"promptTokenCount\": 57,\"candidatesTokenCount\": 10,\"totalTokenCount\": 176,\"trafficType\": \"ON_DEMAND\",\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 57}],\"candidatesTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 10}],\"thoughtsTokenCount\": 109},\"modelVersion\": \"gemini-2.5-pro\",\"createTime\": \"2025-11-19T11:04:41.912108Z\",\"responseId\": \"SaQdaezVN9aD0ekPxJfk-Qg\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.471145375s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1956
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Add and multiply the number 2 and 3"}],"role":"user"},{"parts":[{"functionCall":{"args":{"a":2,"b":3},"id":"1","name":"add"},"thoughtSignature":"CjYB4/H/XqxbQHp2lO9C6z3WWzvVvCiyYUrbBx1L6sQ7hZMExUrufaOgtboKjNVDxYTfY4AsVGcKagHj8f9e1baijGdlfKMfiyGh7mqF3XxfqA9oBZ0mq80e35Kg/CFJiNoFvmmg5vzmSNFq+VLsp92Hw1SCypKySEiF01T0znZgyHN0XwoHeKXAgKk1zFd/Mh9qSsLSC/TPC4vMzjL0qu8Y9RwKZwHj8f9e76FXbccQAPVDxI0QWNsv8dAlgeOaMF1nWU5bouU3cBMwhHFlxz3vz6Ke7XSUiaRYCKz02ZkAd+nxIhHQCCdsl+UUxeybFhfcnmXkIt+zCNFE6SN27CGNDksDumieTr1ZuwIKmgEB4/H/XirqiC8E/xdsBnuN9R4FskbNkWDsLZEenVvz5z3xEAYNGZQpWrw11Wbh/djAiI+HLKgR7VNL7wIbCLO9Jp49wXmNYQg07zeT08rxomsPAHzQAx2TbhoYlMyQSgh/P2aV9yQyGoqaed6NWw0LcKH6RADevMvjfsSxSqb7XHDd7FsSlz+khkGU+gAPSc/rWKBIIz5HakAkCqYBAePx/14T3qNkdp51GdNccS6BIdTKyfkJyjEzghaYr/+sX9aMa2nEpZRrkFj2j6lhorejLvuTBzKDiFQzebD+cTO6ajefAsMsvlO/4+QQ6oF/DviC/T/DIV5N2sf4FbC2qdiR+rfeplH3OYy3XYVlVhjlDc/ruvla0lMhRjlSHscPCCI4mBzaMRlgfWC3rGlrat2Mvw/Vpfg8U5t0vyxsS/mu+BWgzQ=="},{"functionCall":{"args":{"a":2,"b":3},"id":"2","name":"multiply"}}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"add","response":{"result":"5"}}},{"functionResponse":{"id":"2","name":"multiply","response":{"result":"6"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant. Always use both add and multiply at the same time."}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}},{"description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"INTEGER"},"b":{"description":"second number","type":"INTEGER"}},"required":["a","b"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \"The sum of 2 and 3 is 5, and their product is 6.\",\"thoughtSignature\": \"CiQB4/H/XgEAff7RDml+8hx/1vk6IUdWokgmFVPH856Slu3zxmUKVwHj8f9e0iELx1VVsnz2CSRw1K0XNV6ScsQx9SkmpZPl5TIhANatKRSUmuKstVbZUBc/aAi9bBMR913yy474PxR9Vf20Bt+bD+sKQ2DuCUSMQeeKNtYoiwpZAePx/172xjNlka1OXW00nDDuriJX6ldv83VQ/bby5CMLN3+/K5MpNE/tlci8CT+l7YY9YMNPycjWX9p05JezAtkTeQnWmGdDycRpY9WzRz+AsoO7N3xQEcQKlwEB4/H/Xr61E3Q0KGZahZ7tuVVGq7wHbYO4/VfTZ6DuQTW3Fpu8xPEKnmWxKNpihVxV/PzfN748f6defVwCng7ZfFkXJzRmBnx5Q1evgyF0X4v1xtLyFy/sIwbtRqFd2zNKpQuPLq1AfsMAyR0nCtpLPumK7mQrn5OztVFcpa7jiOPZslDZXn+FeIaueokQt/4d0L9OPwNL\"}]},\"finishReason\": \"STOP\"}],\"usageMetadata\": {\"promptTokenCount\": 73,\"candidatesTokenCount\": 19,\"totalTokenCount\": 160,\"trafficType\": \"ON_DEMAND\",\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 73}],\"candidatesTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 19}],\"thoughtsTokenCount\": 68},\"modelVersion\": \"gemini-2.5-pro\",\"createTime\": \"2025-11-19T11:04:44.373725Z\",\"responseId\": \"TKQdad3nFpeI0ekPpeWk2Ac\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.575863208s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/simple.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/simple.yaml
new file mode 100644
index 000000000..82a99cb1b
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/simple.yaml
@@ -0,0 +1,70 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 202
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Say hi in Portuguese"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "role": "model",
+ "parts": [
+ {
+ "text": "Of course! The most common ways to say \"hi\" in Portuguese are:\n\n* **OlĆ”** (pronounced *oh-LAH*) - This is the direct translation of \"Hello\" and can be used in any situation, formal or informal.\n* **Oi** (pronounced *OY*) - This is more casual, like \"Hi,\" and is what you'll hear most often in Brazil.\n\nYou can also combine them with \"How are you?\":\n\n* **Oi, tudo bem?** (Hi, how are you?)"
+ }
+ ]
+ },
+ "finishReason": "STOP",
+ "avgLogprobs": -1.1641908612167626
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 9,
+ "candidatesTokenCount": 114,
+ "totalTokenCount": 1001,
+ "trafficType": "ON_DEMAND",
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 9
+ }
+ ],
+ "candidatesTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 114
+ }
+ ],
+ "thoughtsTokenCount": 878
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "createTime": "2025-11-19T11:04:09.768454Z",
+ "responseId": "KaQdacbzLpTEptQP6pORgAo"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 10.878821375s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/simple_streaming.yaml
new file mode 100644
index 000000000..ba0ac436e
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/simple_streaming.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 202
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Say hi in Portuguese"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"}}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \"Of course! The most common ways to say \\\"hi\\\" in Portuguese are:\\n\\n* **OlĆ”** (This is the standard \\\"Hello,\\\" and it works in any situation, formal or informal.)\\n* **Oi** (This is a more informal \\\"Hi,\\\" and it's extremely common, especially\"}]}}],\"usageMetadata\": {\"trafficType\": \"ON_DEMAND\"},\"modelVersion\": \"gemini-2.5-pro\",\"createTime\": \"2025-11-19T11:04:21.427607Z\",\"responseId\": \"NaQdadeMGo6C0ekP1u_dqQs\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \" in Brazil.)\\n\\nYou might also hear:\\n\\n* **Bom dia** - Good morning\\n* **Boa tarde** - Good afternoon\\n* **Boa noite** - Good evening / Good night\"}]},\"finishReason\": \"STOP\"}],\"usageMetadata\": {\"promptTokenCount\": 9,\"candidatesTokenCount\": 106,\"totalTokenCount\": 815,\"trafficType\": \"ON_DEMAND\",\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 9}],\"candidatesTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 106}],\"thoughtsTokenCount\": 700},\"modelVersion\": \"gemini-2.5-pro\",\"createTime\": \"2025-11-19T11:04:21.427607Z\",\"responseId\": \"NaQdadeMGo6C0ekP1u_dqQs\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 8.8158165s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/tool.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/tool.yaml
new file mode 100644
index 000000000..53a501432
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/tool.yaml
@@ -0,0 +1,142 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 509
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "role": "model",
+ "parts": [
+ {
+ "functionCall": {
+ "name": "weather",
+ "args": {
+ "location": "Florence,Italy"
+ }
+ },
+ "thoughtSignature": "Cu4EAePx/14ljyE7z5hE6T9t7Cpe3xNFuB93gWa2T9NLfeE459sJp1VDMgbMx/6eM/sTYTOGkK/KU5UiVl+Kc5sQB3S6DYZfyn0K/yJmKxcXH27PwGXE7mBs4u45F3Tb+7mQHr0E5LroPO8LXN4J/UFb6g977nMHeJFXFxuQWU+tqtRy7gHRF+5ykdRmzHCkjHiCxuMO+KlJbU7PvX76b1seSG47Y+jaa/saPxnVSV1tLpTV+N6jujTYPcsgY/0+zzyERBve0PVpbGTlD2BBGOaOCG+6C0fQjS2kqgIceGWhzwfbAbl+LvaruGqmjx8lGLcXcOlbtKOlZtPQJg8gyIHGG1JB9Ufg5XD94MZ1ie4z+WCsfqtigiKKu6ndLSsycnntb1XLEhhAh+aoSab+MJf83SWnM7hvNCwLzIt7AFyWLKEDPW2sOYBtIyvR1RSCUEZqcbEwnsLdt4vzTVDsktoSpKAybdnN9MZ58z8AXsYhhumOCOxTn4mZvMXd6UBAmcOafK3awfh8CWrEc/+l1PBzsYWMepHXxEiYk53uXfz8eUTERXe9snKacpDiZTjiljFvtxMUSFXrcUjGL9GgH+2aQ9d4tunJ6sObwLodMJlYTrLNMIbEcKehmW4vEJ56ETT+6J9CfxB2SeQmfbLMsrUCmcY3yaP5qwNx6PQc/Wwi2lrYWec70EopPuOIT9/Yo/QcPTlqhsm7QrMLfflMtmGkqTUBUFOCOovA1ZzLhz+k+QsZNBjaGs62AXlgW5Y4779WMgoTOyFWdDAld6kVOOzHjHACVEfIdMlpSnbLQytA+Ri7GwoxxFv1TXlmYSXZXQ=="
+ }
+ ]
+ },
+ "finishReason": "STOP",
+ "avgLogprobs": -0.74591360092163084
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 28,
+ "candidatesTokenCount": 5,
+ "totalTokenCount": 180,
+ "trafficType": "ON_DEMAND",
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 28
+ }
+ ],
+ "candidatesTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 5
+ }
+ ],
+ "thoughtsTokenCount": 147
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "createTime": "2025-11-19T11:04:30.222222Z",
+ "responseId": "PqQdaY7IDaOA0ekP6aHL2Ac"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 2.247443792s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1580
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"location":"Florence,Italy"},"id":"1","name":"weather"},"thoughtSignature":"Cu4EAePx/14ljyE7z5hE6T9t7Cpe3xNFuB93gWa2T9NLfeE459sJp1VDMgbMx/6eM/sTYTOGkK/KU5UiVl+Kc5sQB3S6DYZfyn0K/yJmKxcXH27PwGXE7mBs4u45F3Tb+7mQHr0E5LroPO8LXN4J/UFb6g977nMHeJFXFxuQWU+tqtRy7gHRF+5ykdRmzHCkjHiCxuMO+KlJbU7PvX76b1seSG47Y+jaa/saPxnVSV1tLpTV+N6jujTYPcsgY/0+zzyERBve0PVpbGTlD2BBGOaOCG+6C0fQjS2kqgIceGWhzwfbAbl+LvaruGqmjx8lGLcXcOlbtKOlZtPQJg8gyIHGG1JB9Ufg5XD94MZ1ie4z+WCsfqtigiKKu6ndLSsycnntb1XLEhhAh+aoSab+MJf83SWnM7hvNCwLzIt7AFyWLKEDPW2sOYBtIyvR1RSCUEZqcbEwnsLdt4vzTVDsktoSpKAybdnN9MZ58z8AXsYhhumOCOxTn4mZvMXd6UBAmcOafK3awfh8CWrEc/+l1PBzsYWMepHXxEiYk53uXfz8eUTERXe9snKacpDiZTjiljFvtxMUSFXrcUjGL9GgH+2aQ9d4tunJ6sObwLodMJlYTrLNMIbEcKehmW4vEJ56ETT+6J9CfxB2SeQmfbLMsrUCmcY3yaP5qwNx6PQc/Wwi2lrYWec70EopPuOIT9/Yo/QcPTlqhsm7QrMLfflMtmGkqTUBUFOCOovA1ZzLhz+k+QsZNBjaGs62AXlgW5Y4779WMgoTOyFWdDAld6kVOOzHjHACVEfIdMlpSnbLQytA+Ri7GwoxxFv1TXlmYSXZXQ=="}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"weather","response":{"result":"40 C"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "role": "model",
+ "parts": [
+ {
+ "text": "The weather in Florence, Italy is 40 degrees Celsius.\n"
+ }
+ ]
+ },
+ "finishReason": "STOP",
+ "avgLogprobs": -0.023431075470788137
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 38,
+ "candidatesTokenCount": 14,
+ "totalTokenCount": 52,
+ "trafficType": "ON_DEMAND",
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 183
+ }
+ ],
+ "candidatesTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 14
+ }
+ ]
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "createTime": "2025-11-19T11:04:32.497194Z",
+ "responseId": "QKQdaaqsHomA0ekP5JSJ8Qc"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.2568785s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/tool_streaming.yaml
new file mode 100644
index 000000000..49f489eb9
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleCommon/vertex-gemini-2-5-pro/tool_streaming.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 509
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"functionCall\": {\"name\": \"weather\",\"args\": {\"location\": \"Florence,Italy\"}},\"thoughtSignature\": \"CiIB4/H/XuGEqIkixg/vsdLNO/XLdMRIZWrA4iDLpx8bp1ChCmUB4/H/Xoj6y7XCdrBliXjSjdFbjGTIHnTA9YwnccwE2dLTxHzOJ92RLCPgzO88hXs1xOzNXD8+/BC4WYDIxscHvvQevTaThD9T9w2ZR+yCElxo+PwMgDiuPFGHkB+XEtVivx1chApjAePx/14yHfyzssNIJ5Kw9cHYnXQl1hlVSRM0suf+tqfI+vE5FCVa7mhohZRmW36oYdjWkeKEIKALgBBr5C5Q+MZujY9w1b+jW+Dah66ucWpODv1LOlet4qMPuRwr/zAZ/iRSCqoBAePx/16kFfr13j/F3N5RIbe2LZPv1Jz49ZsxKJelffFaZMMCxlLIgAi+cSEQejQj3J7nehUSvpi6e6Q29QOdXZn4s089OPoZ4wvnRU4BIU5RC1OUZGrAmPv8kocrjkGr/pXTEjQ1mirmG3OX74GA+ISPTHFclQZVREd9QNp1wRsFejJ9HKVTd8f9jOhfuUuWOSBw8jW1MpSvQ4lb5rkHVogo5qVirprIFbEKrQEB4/H/XpvI9HymzllORqZ25uT8VLEfc0qPs61CgMxYMsfgL0asvIcdSB02N0pXYmiRDLjLR1T1Pkh8c/L7M0G7PTvtoNjPMzkdz0msb3Odf8LiLQWtyMbiPwjxGU7s8rsnN65To+VKIl5pyNxtyIThgA4haz1f2V6ygnu/JT1TFUd31YH2je7q1Olg9rgyy6X4Pp7mKToTqnt3yIjSU7PAbirotUM6T6kZz7tEkgqRAQHj8f9elrIUctW0pfELICfLw6h2P7DLspahCrZm2AOGGJfKoe7WA+aMM9LakL2teH+QOSmoeoRNQuBJUwe9l8dMGPEUcGixd/iyxTyKs0krpQsHlsxK3iGbuAcqNXNJxgCS1DpbW81yZ7pOFgPjnRFnD+/ctSGHBMwIffEaPruRkbE1HCCBVh8DE5kHeRJ5jK8=\"}]},\"finishReason\": \"STOP\"}],\"usageMetadata\": {\"promptTokenCount\": 28,\"candidatesTokenCount\": 5,\"totalTokenCount\": 164,\"trafficType\": \"ON_DEMAND\",\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 28}],\"candidatesTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 5}],\"thoughtsTokenCount\": 131},\"modelVersion\": \"gemini-2.5-pro\",\"createTime\": \"2025-11-19T11:04:33.920749Z\",\"responseId\": \"QaQdaa2ZOKKA0ekP7dGKsQc\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.54737625s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1728
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence,Italy?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"location":"Florence,Italy"},"id":"1","name":"weather"},"thoughtSignature":"CiIB4/H/XuGEqIkixg/vsdLNO/XLdMRIZWrA4iDLpx8bp1ChCmUB4/H/Xoj6y7XCdrBliXjSjdFbjGTIHnTA9YwnccwE2dLTxHzOJ92RLCPgzO88hXs1xOzNXD8+/BC4WYDIxscHvvQevTaThD9T9w2ZR+yCElxo+PwMgDiuPFGHkB+XEtVivx1chApjAePx/14yHfyzssNIJ5Kw9cHYnXQl1hlVSRM0suf+tqfI+vE5FCVa7mhohZRmW36oYdjWkeKEIKALgBBr5C5Q+MZujY9w1b+jW+Dah66ucWpODv1LOlet4qMPuRwr/zAZ/iRSCqoBAePx/16kFfr13j/F3N5RIbe2LZPv1Jz49ZsxKJelffFaZMMCxlLIgAi+cSEQejQj3J7nehUSvpi6e6Q29QOdXZn4s089OPoZ4wvnRU4BIU5RC1OUZGrAmPv8kocrjkGr/pXTEjQ1mirmG3OX74GA+ISPTHFclQZVREd9QNp1wRsFejJ9HKVTd8f9jOhfuUuWOSBw8jW1MpSvQ4lb5rkHVogo5qVirprIFbEKrQEB4/H/XpvI9HymzllORqZ25uT8VLEfc0qPs61CgMxYMsfgL0asvIcdSB02N0pXYmiRDLjLR1T1Pkh8c/L7M0G7PTvtoNjPMzkdz0msb3Odf8LiLQWtyMbiPwjxGU7s8rsnN65To+VKIl5pyNxtyIThgA4haz1f2V6ygnu/JT1TFUd31YH2je7q1Olg9rgyy6X4Pp7mKToTqnt3yIjSU7PAbirotUM6T6kZz7tEkgqRAQHj8f9elrIUctW0pfELICfLw6h2P7DLspahCrZm2AOGGJfKoe7WA+aMM9LakL2teH+QOSmoeoRNQuBJUwe9l8dMGPEUcGixd/iyxTyKs0krpQsHlsxK3iGbuAcqNXNJxgCS1DpbW81yZ7pOFgPjnRFnD+/ctSGHBMwIffEaPruRkbE1HCCBVh8DE5kHeRJ5jK8="}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"weather","response":{"result":"40 C"}}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \"The\"}]}}],\"usageMetadata\": {\"trafficType\": \"ON_DEMAND\"},\"modelVersion\": \"gemini-2.5-pro\",\"createTime\": \"2025-11-19T11:04:36.481439Z\",\"responseId\": \"RKQdaZ-xHa6B0ekPlJO-oQk\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \" weather in Florence, Italy is 40 degrees Celsius.\"}]},\"finishReason\": \"STOP\"}],\"usageMetadata\": {\"promptTokenCount\": 167,\"candidatesTokenCount\": 13,\"totalTokenCount\": 180,\"trafficType\": \"ON_DEMAND\",\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 167}],\"candidatesTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 13}]},\"modelVersion\": \"gemini-2.5-pro\",\"createTime\": \"2025-11-19T11:04:36.481439Z\",\"responseId\": \"RKQdaZ-xHa6B0ekPlJO-oQk\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 803.423291ms
diff --git a/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-flash/complex_object.yaml b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-flash/complex_object.yaml
new file mode 100644
index 000000000..6ff9f0fd1
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-flash/complex_object.yaml
@@ -0,0 +1,62 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 817
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about 'The Lord of the Rings' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954)."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"author":{"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"responseMimeType":"application/json"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"fantasy\",\"adventure\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 38,
+ "candidatesTokenCount": 41,
+ "totalTokenCount": 230,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 38
+ }
+ ],
+ "thoughtsTokenCount": 151
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "responseId": "yaIdaduGCfahxN8P3p7vwQc"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.690439333s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-flash/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-flash/complex_object_streaming.yaml
new file mode 100644
index 000000000..52dc75f19
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-flash/complex_object_streaming.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 817
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about 'The Lord of the Rings' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954)."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"author":{"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"responseMimeType":"application/json"}}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"{\\\"author\\\":{\\\"name\\\":\\\"J.R.R. Tolkien\\\",\\\"nationality\\\":\\\"British\\\"},\\\"genres\\\":[\\\"fantasy\\\",\\\"adventure\\\"],\\\"published_year\\\":1954,\\\"title\\\":\\\"The Lord\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 38,\"candidatesTokenCount\": 37,\"totalTokenCount\": 210,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 38}],\"thoughtsTokenCount\": 135},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"yaIdaYqFMfuDvdIPn_iEyAk\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \" of the Rings\\\"}\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 38,\"candidatesTokenCount\": 41,\"totalTokenCount\": 214,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 38}],\"thoughtsTokenCount\": 135},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"yaIdaYqFMfuDvdIPn_iEyAk\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.379188208s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-flash/simple_object.yaml b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-flash/simple_object.yaml
new file mode 100644
index 000000000..4ee78db35
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-flash/simple_object.yaml
@@ -0,0 +1,62 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 499
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"responseMimeType":"application/json"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "{\n\"age\": 30,\n\"city\": \"Paris\",\n\"name\": \"Alice\"\n}"
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 20,
+ "candidatesTokenCount": 25,
+ "totalTokenCount": 127,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 20
+ }
+ ],
+ "thoughtsTokenCount": 82
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "responseId": "xqIdab_LEP7hxN8PyeLZ6Ac"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.1166025s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-flash/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-flash/simple_object_streaming.yaml
new file mode 100644
index 000000000..0f1c4b51e
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-flash/simple_object_streaming.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 499
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"responseMimeType":"application/json"}}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"{\\\"age\\\": 30, \\\"city\\\": \\\"Paris\\\", \\\"name\\\": \\\"Alice\\\"}\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 20,\"candidatesTokenCount\": 19,\"totalTokenCount\": 133,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 20}],\"thoughtsTokenCount\": 94},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"xqIdabK5MLfbvdIP6NWWuQk\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.214252541s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-pro/complex_object.yaml b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-pro/complex_object.yaml
new file mode 100644
index 000000000..6d1dd36b0
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-pro/complex_object.yaml
@@ -0,0 +1,62 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 817
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about 'The Lord of the Rings' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954)."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"author":{"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"responseMimeType":"application/json"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "{\n \"author\": {\n \"name\": \"J.R.R. Tolkien\",\n \"nationality\": \"British\"\n },\n \"genres\": [\n \"Fantasy\",\n \"Adventure\",\n \"High fantasy\"\n ],\n \"published_year\": 1954,\n \"title\": \"The Lord of the Rings\"\n}"
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 38,
+ "candidatesTokenCount": 84,
+ "totalTokenCount": 195,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 38
+ }
+ ],
+ "thoughtsTokenCount": 73
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "responseId": "0qIdaciCFffPvdIPp-ycyAk"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 2.813791334s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-pro/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-pro/complex_object_streaming.yaml
new file mode 100644
index 000000000..5a8200d8f
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-pro/complex_object_streaming.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 817
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about 'The Lord of the Rings' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954)."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"author":{"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"responseMimeType":"application/json"}}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"{\\n \\\"author\\\": {\\n \\\"name\\\": \\\"J\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 38,\"candidatesTokenCount\": 14,\"totalTokenCount\": 188,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 38}],\"thoughtsTokenCount\": 136},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"06IdadTyD9b9vdIP4ITmwQk\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \".R.R. Tolkien\\\",\\n \\\"nationality\\\": \\\"British\\\"\\n },\\n \\\"genres\\\": [\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 38,\"candidatesTokenCount\": 38,\"totalTokenCount\": 212,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 38}],\"thoughtsTokenCount\": 136},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"06IdadTyD9b9vdIP4ITmwQk\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"\\n \\\"fantasy\\\",\\n \\\"adventure\\\"\\n ],\\n \\\"published_year\\\": 195\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 38,\"candidatesTokenCount\": 60,\"totalTokenCount\": 234,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 38}],\"thoughtsTokenCount\": 136},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"06IdadTyD9b9vdIP4ITmwQk\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"4,\\n \\\"title\\\": \\\"The Lord of the Rings\\\"\\n}\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 38,\"candidatesTokenCount\": 76,\"totalTokenCount\": 250,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 38}],\"thoughtsTokenCount\": 136},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"06IdadTyD9b9vdIP4ITmwQk\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.114800584s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-pro/simple_object.yaml b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-pro/simple_object.yaml
new file mode 100644
index 000000000..ec328ed4b
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-pro/simple_object.yaml
@@ -0,0 +1,62 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 499
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"responseMimeType":"application/json"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "{\n \"age\": 30,\n \"city\": \"Paris\",\n \"name\": \"Alice\"\n}"
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 20,
+ "candidatesTokenCount": 28,
+ "totalTokenCount": 112,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 20
+ }
+ ],
+ "thoughtsTokenCount": 64
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "responseId": "zKIdabLLD5GavdIPxvbZkQ8"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.691421375s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-pro/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-pro/simple_object_streaming.yaml
new file mode 100644
index 000000000..ac82ab49a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-2.5-pro/simple_object_streaming.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 499
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"responseMimeType":"application/json"}}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"{\\\"age\\\":30,\\\"city\\\":\\\"Paris\\\",\\\"name\\\":\\\"Alice\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 20,\"candidatesTokenCount\": 13,\"totalTokenCount\": 296,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 20}],\"thoughtsTokenCount\": 263},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"zaIdafuIG7KlxN8P_d3JsAg\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"\\\"}\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 20,\"candidatesTokenCount\": 14,\"totalTokenCount\": 297,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 20}],\"thoughtsTokenCount\": 263},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"zaIdafuIG7KlxN8P_d3JsAg\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 3.282518084s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-3-pro-preview/complex_object.yaml b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-3-pro-preview/complex_object.yaml
new file mode 100644
index 000000000..266c4c9d1
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-3-pro-preview/complex_object.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 817
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about 'The Lord of the Rings' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954)."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"author":{"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"responseMimeType":"application/json"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "{\"author\": {\"name\": \"J.R.R. Tolkien\", \"nationality\": \"British\"}, \"genres\": [\"Fantasy\", \"Adventure\"], \"published_year\": 1954, \"title\": \"The Lord of the Rings\"}",
+ "thoughtSignature": "Ev0RCvoRAdHtim8IbVoKzHu9DSiZ/yt55YYnW37+8kYX3lqSg5uk5kw71CkPqWhKJ6AXQFWon5dBWqSD3do+jhJx+yGDcyRxHiJgqVozeb24Wxls8TyIQyU9WftAzMoSm6wnO2paOtm9DV7a/cIiy4UIHTQecWF+GBxPgfUyuxWiFXsQ6w8ixovCvhboL/toE9JYcgLsLRw8hdBV8XhrDNu5Si4CkQi5Us5L1GqWLFcIk0Td5vlTWp0f51BFStujmDDtE/MDmuOgx1KO14TUddgZuYUxOFpizG433SSfCz9/eOT9FWWwga36siLgp525fLJ+2FbXOu08UIKWZVW/Gp2TCeDTj1AWYC6QqcYCBdWVy3pqKseEtXkxt0bTyKFbBGwTiklH+LrMmvN5AyDVYKdLV/Qc35T/3BrCPKQyBUyJK6aIkDP2i0sY7yHRfjTSiy1Bbj+h27AcwKkr533nNMNPPYK9goQtRtjrqOUXIA6g9ryIx2TsFOPJyi08MSIyCK/fM4ojpg477f7yRaKRd0x5BcV0tt9L7280AvEBhTs64XUorFgoT6J+WDZAJ+FQYL0VWDUkQkTu6u7BfmH9Fjc2q0YE/jxNK64Wmgmm57xT6vSrVhnUFgKsCN/M+nMbf5n3fSx6FENHZ7ZhbUu1AsiKYxwZL8S9B0WaQkws7au9BlUa9HW5kMcf0y5AzgiqHiTpJXqdAfs/vxm6nIDj/Fmz7ZjH1M2/8EM1PxRHN8MzCZ4WfSv29bh8+PC+neQXsBuJ/LYPEyWcOOlFLtJ4X3PGqoUgUsgOJaqgKaWlySy6wghS5sq8xC73zt7cbSurryteHGW46xl9MezT6ngEvNbi3rSXBxu6dSQMJAJ9ZXQqX+x5MS6UiLn3N0IboiqleHhiYNPNM2zHHFudTo/nRoAav0gu+b1PHn9njPiVxMlQ3gttPN/z+hNLvO56JE27tWxVQE+/ZpjRRRlgJ2chuAgBMA50EWYFGnqyNOer44nGtUcr5xgUEJV8YbUbUgEPGLN/QXa2nElR2+oCqbvax8hODOu3lji6o1ozq9PPzHDxVf8kjVkxULM4DtRiCgvXkzHlAOGov+PyDOIETE7e4U9hIG8vbHcAaHPymoy/JiyIqtb4qI7450oMlUAi08PmiQnmKlKHxYmTXo46M5R2i83evkVHE6rdCmwaxd5iIwTeNUj4/CtUPCiEUVSmYUqkYgTuQl4jZLuNyJzyiriYHSgTwUYbHS5yhkdhY3n6pNJf+aEWNLViIF7rpfU9BWGKXat5206gavvuGfxaz4e+fbb44atFAeJ20YJX1SOm5nlLDKOeMVmHhlqW3422UD8bqgdSBG+Elqm48h1o7rw+iVFpyxdveruFJ9r8ZFIhYKYHCmSyszhmRcwcmqjGbGHXBtujvcAzeu/b8N9YiTK9AEnR1IECZfmD+/+T2TpecfCNMZamFFB0Jx7OiManf36NJyZJ5+3JhrkSQTKqlFn/IhKbn5ThP36Yp32mza4GvzheboTmktmoUD6c5TLJ6g6wcLqTb6pxPvCBBsqICt3zVE6Y8DrursqfLsEFjFx73VGwlaD0DgsVvSA7Ty5bEaVTiiRg5ZuEwXaOxr8FEDPLCYp/uyO/H5MnXb8b3NMJYWmSSeXj0T8a8DQ0SvX8B2J9zQUT2ZSTVhpw8uULAKtortAL5NF7musMoUvPIzhAXkE9u9zK+CA9H5Lj/jl5dC9Uou2UDHWk1D76h23tmvU5fbih5w9V1cAwlqAHTlW6AEWlmSDYaHDj9h1C/FkAMOOc0L+26mAt9SEzGJ89YTdIte57ZeKHc1JiaXN4sVoc1A7wuDbrjooEE+DTgKQbUoiWX2KVoszYfBdhANiJX/sfd5rkfZVCFT0l07QLltwzOi6YFWN2gIyV3/pvOU8Pubdi8eQvxPel8wPUNS0N6n6S74D6A3ue5pJgeAVxl55sOXOyotGjAIqIEWWWrf6yW9ie+0p3YurQYlXWhjdOOnXnxtngSqq0mi0skN4TrU2kwov3IWgL8PTDPyRv//wMlP1VynzF74vZrqUxxrdursAZpnGURZSA3Ev7ROHCu2N3lIQ3KarPjD+MjLDxVaEqgBeLVIA35hSjKuRxmiUocpO97I0VlrTQj8ugaZBXw0I9kc2esaeUIbRDeRf2rqKiqH1b8yyGZiBD94MVo/PnDhNMd5waw1yhY+vcUk9Pq0+Vv5qplF7APVoDY+3I0Bd8c8ccM9x8FT5JYg7GNyz+LzRLs5GMoKrd5pOC1WbAebR51fpkCHyi76UfSGz2ST9Z9NCu9oY2imLH5RFWsxHwk4DRrhDKek7cT4ZuBNldK1sAA908ihhUvRWI+4itTlC0K/+GNMnbEUKf3DEX0zOPOVzPeWfmdD3On62u9PMDMA3rTn22IgOH/7eXFVMRuKFCgW2/8CIrKlq4CdoPMm+vwH603ExycKvFbvdtBJD1BSbHaLhui4YRsOzcoco+iYAQQnc03H7FzNAyPJ6XudCBCf79XV32CpSlM5rsURW8pYfKnzWpN0NPDmYNsRVTCZzJAc+G5dBiYDt551jXUZGrv9eK5aAXmhksbTst7cKz50kHjZrP33s2q410ZF2wu4scnOFxvBJeb1bl1xKH4lWMrSAi85I2pfZvbMriJzWcDjoGBNWaHHYe/4qLCS2iuQKOzzIGT2IUVPH656aF3q4HcQpcPCUaixihrEp/GRU/pGv+2jkemdCYf9SxtuCaECCZyQN9JAh8+BZHKUh5yO/XqQoj+uRjzDdIBA0gBh9lyvRXXLN6chQ4bd+DxpxXnrjf373YYBNbLp5t+1oDbrrO/PYrKz1p1CUXAUkM/KFLW3E08ZQ19HNirif+edyCKB/CQQtw05vWZkngTXdwbOsvGhLY3jXoOGCrqNOQrewWCHWFmjf2JxTXaaeEi3fXyX0VPTDrjuHpz7barc9z/xfkDj+bm0aIStPrRYfT7eB1IAAQ/fu13Aa1wRac/vHrZAZFAa13/8aHgUjCnu1w+YQF0wB8vIB+0QHjolPdvgv4L79Uf/jxsfN4TyLW1yPnGs9bL0vt"
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 38,
+ "candidatesTokenCount": 51,
+ "totalTokenCount": 747,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 38
+ }
+ ],
+ "thoughtsTokenCount": 658
+ },
+ "modelVersion": "gemini-3-pro-preview",
+ "responseId": "v6Idae2xKIDXvdIP097RmAg"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 7.5885605s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-3-pro-preview/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-3-pro-preview/complex_object_streaming.yaml
new file mode 100644
index 000000000..431dd3342
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-3-pro-preview/complex_object_streaming.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 817
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about 'The Lord of the Rings' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954)."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"author":{"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"responseMimeType":"application/json"}}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"{\\n \\\"author\\\": {\\n \\\"name\\\": \\\"J.R.R. Tolkien\\\",\\n \\\"nationality\\\": \\\"British\\\"\\n },\\n \\\"genres\\\": [\\n \\\"Fantasy\\\",\\n \\\"Adventure\\\"\\n ],\\n \\\"\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 38,\"candidatesTokenCount\": 54,\"totalTokenCount\": 564,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 38}],\"thoughtsTokenCount\": 472},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"xaIdaeu3AtWNvdIPo9-nuA8\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"published_year\\\": 1954,\\n \\\"title\\\": \\\"The Lord of the Rings\\\"\\n}\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 38,\"candidatesTokenCount\": 78,\"totalTokenCount\": 588,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 38}],\"thoughtsTokenCount\": 472},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"xaIdaeu3AtWNvdIPo9-nuA8\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"\",\"thoughtSignature\": \"EqMPCqAPAdHtim/qoClpB6Fl4IGbJM4ZYPxj4nlVArCL0UhKPbeG9D4l+wRoKuaWH96pLNpqU3B78AkB4JXsx0XKp8xv/Rz+sKgDqBAuMgV29GQc9flyvyX5T2fYEpnxFz+HiVtPrPhUeIM3WcEMNQdbmrAgCgBgYP7m5BxWQImTWtCYN7tvsMS9Sgsiz8nGRhe3Pj+AtWLSwCSwgSbO+7eCEZlLAovg24jIUvvzGk0nT82DRxpaQZNb4iZVLd8wKYX2lkBv7VEAyq/H6X34lTa4Ok9Jcpdns6c3j9oiDZmCwROfHoOGOs+bk35jEnrYWgdx8v8jS6yachQnwGQcnVkvdMCHzVXd7EaelY4YcxDQU72NYzpACmq8+1+3uFQj/22iHIqhGwuwaVScRxOKRp9+Y37acOkQFOtzsWlU7wKdlO95HcFtIp3gv1lyowYRKXMUKD0mq9dHl/xWL1WFL+moYgvmZoxounnm3n49TNdkqsfT5A+XyLyqUmcuyFOV0EXRaQBeazuK6smO8Knw6ZH3vElq7RoE1vvnclp5ghh2yP/5rWAyz8VtpJE46jPjt6yiifez5todGl2A4BK29U3mQIJqBS5JrdjAwK288aEsP1raBA6Je4Hef3S6pPUohBeLW9WFzZxjvmZ4De1rCByUSBj7oJaq8o//y1ng+31C0VXUlahuv79GfJcTlevo3Gy2EV+gLl5nLio+W3qURFeojrfGxwAQpNegaKjzr8LwSPX1rjY3dEJncNjUeB8DcLvCZ+vFXWF68/SWZw6q8mRSXtrADxUtlKx1Guus8fa3FhxdpGPlXdK36HaZWPfa3Hi2gPtZmq8rD4z55R4I+KSNW8jkjsE23v8dXrAcGnFcCs3u/FVvwnX15PDGWVs5rLwB33x5QJ5fZa55fgr4BO6axSSEa4EAhEthSXZ0H5XW1k3fAP1+pGWA2udfRJDOXRX5vMzZIsWWnwICG0rfj7akPPEkbXS+8z7KO6AlCGxjJoxBqS8fStoaCQ5pEvYUwNjLcpwtjeCAD/2LvRG2ZmOvtG3/RUPjYEuiQwc0tee2lLXCeNPv0G692XUUpe8ZVSXkLX5D9dPkq4aRZuv0JSuuZWWhkZIgjyvTns5ba2ISfLD6o1GNhTWhYDSi7LFg4Gc0k1lvtiIE94rNafAPrWmNFENxq2J6dFac7coG8mX3rakHQ/5azvW38DwlKh3vYSFg2oIanK1+4Pc4kBmQ/hscN1/2J2RXoqv7l52IXg0m6e3mgpis8TTYpvkCu7jRKnfRe5z6o13VmlW6jvwzUC/DBU/3n4rH18mlvb2ZjKiRjmZYWMyzc0cJNjR9K8ZZhPm4YRLzpeTuaisZvZXonSBJn1UCsrun3OFSyOn/aPr/+f0i86rRvK0SAjDw6LM80Xy/Mm7wnqRPkR93VXf9CRVyz7glt4ApcGkSbwkePFcsTEXq16wDIi6YgI8i9MZpb0lkCxzWTmyR2Oh3JWm8CHMf5OLM+lFqszPmyc0LOZdUcEM/M2sHt/SuSLtxnjtJ5Q6TemZvkctTugA6KzKPkeClzVlOYohJnVhqyo0pO2UZkhhWbmJ8BvLma3xKbs1dpTG0WpsWRiXoxcMBczYBoQWbbiJfp7UMCSicJuhzXJHsL/ANdbdWvw90ah3h26OBrRH+UCdZwumsLtfJGXUTkXYVpjrMrq0dEiuZ8mARDKpTi+CE9fhHBMJ68x2Ki66ZstG5mwgvJMx/vvjXECVCtBj4azL02PwyyPsWzNbT16KJILh3fbFkYEiBpjG3VHa2U8fqMODZgZ+zmC3q9HG2QK4IPqieEmdkEfMaShWdqit6YTR+BXIVkpm4SiQ0FIPYp64U9mfB1xVJrqqq60i/nVfGVXUtfsw7b7BtCoWvHexSUt/JPxV7c/0YHSah22cn7beBESS0QBNR0H85EfAhttq1koKF7DK3ribCvaWv4jtmPnDKLpfORdSnffvAMAm/U4JpcsIT5Hx5Q8BiWUnvDfOuFpONy3QuRu2ri6W4idVYEw7iF7ZWVQWjmUM9EPQ72uKnvmp0R7PKc3i5rYbJ/2IXoXkNkbOshw5Si82HhuBkgnROyY4bIHNyM9SGptzH31wGfkI698F07ENT7VP7hbuti7+kYv0AsA7ofYULyOAzFDJ/0uRHuQHZm50AbscWjZ6/Rh12f4qkeyCaYgs5G3bb7SkFVdCNw5csd01QmUIrds3nw2wZQpSkbsfI1HL84UV6x+wqo05NmUP4ZrU4SZ367Io2QnZ9e7ZIQBQLjuNapCSBhJ5M+E+f3my+He4lFU5JxP4B84pwmlYqWT0kO7Xo+APWDFRC9xmysK4YfMtJyBtmOvZcuM5BTRg8NMknr2DN5z9Q4Mc6ZUy7+Wt+9i5+bMD27+Xjl8n+9sNL0AFJuU/dhHYNDMm7MvXRpUOSV/9gne3eRkxKdHSWqnGwCSaB7KwzJYYxc7SPpI1GK/HpQWZGOvdvLF1g+WfgU2kqs7y31vLrzxLiZU28RVLo9bbV9thVzYld8gCc+8jp7jqFN9/H1ndS8KBRpxsluUs3YOmqNEQ7X8EBFmDmj0knu8lCf98B5lt1wf8QPH5AWV0ZBk4BFwY=\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 38,\"candidatesTokenCount\": 78,\"totalTokenCount\": 588,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 38}],\"thoughtsTokenCount\": 472},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"xaIdaeu3AtWNvdIPo9-nuA8\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 5.357591083s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-3-pro-preview/simple_object.yaml b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-3-pro-preview/simple_object.yaml
new file mode 100644
index 000000000..e1f143aaf
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-3-pro-preview/simple_object.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 499
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"responseMimeType":"application/json"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "{\n \"age\": 30,\n \"city\": \"Paris\",\n \"name\": \"Alice\"\n}",
+ "thoughtSignature": "EvQDCvEDAdHtim/cb1dWV6U1RcEIEknDD+tQ7jQ1cgOCFASlsLpobD0ejF9JGoUh6SZgWrjo54SGYwoEHM2DTRHS5UV44kUrVhIqPkXIsxhNZJyjplQsuL0+JJ3jriwV7dMSx3N6sFeTMzmFWrjzIXWsIG/S6yscqlMp9awgUisApHJXiQmTHsfCh4kxHdLsCuCl+WFrxYRTmGpsgNtgYhNFFw5xUAFtzSocFvlIepFglzOI4ccIrXEn32g2n0bgvq6CX4p2aBDRAcdRztxlblo0cUSRjDPQCsj4rRMpY2yeSI+PIXwsD+w8Vfy4sjGBafSh4bRnoQhc0U6SFRnEKaVxiZhoeWKhSc6usmjcuQDSR8mMFvVul8lsY3vPgn/KC/QCrlIwVYBsLMbhhsG9/LAeijGFzuYRX75D4pVvHxxWyEgdbvHrhT1wVmNJz01F+ZzwrtdWZjMiojhQAMWL8V9ujfQcrBG5JA2oRK/K18fW67seVo2BB3t0Us/jTTULNIqtp7mFz2JaK659n8YOe4IsMXHcQJmFxF793KNGdsQpkyACW9zENV+Idjh7zeABKrpXjmKgJ3wpdhQirzbwNuJG6gphCLDdUUeUUvjSQACjwvtJ0DWdLbJU65WEaBVTLf+hig3mEpwMANItd2caBaU7+fXFBH4="
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 20,
+ "candidatesTokenCount": 28,
+ "totalTokenCount": 183,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 20
+ }
+ ],
+ "thoughtsTokenCount": 135
+ },
+ "modelVersion": "gemini-3-pro-preview",
+ "responseId": "s6Idaf6qKo-7vdIP1aSIwAk"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 2.925005834s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-3-pro-preview/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-3-pro-preview/simple_object_streaming.yaml
new file mode 100644
index 000000000..0c9c62a6b
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleObjectGeneration/gemini-3-pro-preview/simple_object_streaming.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 499
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"responseMimeType":"application/json"}}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"{\\n\\\"age\\\": 30,\\n\\\"city\\\": \\\"Paris\\\",\\n\\\"name\\\": \\\"Alice\\\"\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 20,\"candidatesTokenCount\": 23,\"totalTokenCount\": 426,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 20}],\"thoughtsTokenCount\": 383},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"uKIdaYWJBMmNvdIP66uD6Ag\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"\\n}\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 20,\"candidatesTokenCount\": 25,\"totalTokenCount\": 428,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 20}],\"thoughtsTokenCount\": 383},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"uKIdaYWJBMmNvdIP66uD6Ag\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"\",\"thoughtSignature\": \"Es0MCsoMAdHtim/2g80u7MPzJwy/NBB/OVelAlwSxB95f65Celfa1/NHwKSg6XCbZHl/bLY0pCOBkUqKWnCRwQ9jZ0a18hccEucQRd7QQVf4YrPw4w/rXtiu4kVwtuuuRCoRl/A+bCTu+e70RKHqemiAfvNf+DepnpF9H9vz3BzZ2PXKSgZaOT6PswiM9xXmC6Qv22HN1uxYBVZaDmZGRLmQCqQbgNSXX1+oTcLYue8zNeyhZLtowrJtqSAWnriTV6zda6ANPwhh0V0ADVUgj1wz1/OAHqE5qdHbX5+ksRAjieI4s/Ea6eDRzURdo17+i1zHtH2ajpe1rsMVu1Ft4ng9eQJQXG+dw00jPoENwoO41cc6cOktVOiVNRszlQsJlt3SjZFzfQMJr9UdYHD3awzA1SSvPyQ9WKEUuJDKK3akyfi30frITn9ZxNcXQ91fEiZ8GWLn1oZCKMss7rdkyJ0pfwobASs4CBaqFsZ/6lzAhH0eR3IzrHD3KxJniSfazd01Br0sfJnEUa/GbDSPybRhboleJMsiw7E9kwdEwdUcGbh0ZFxb/6tMN6s165S6v+I3TI28aBw89HzzHFpQv9WGl2V/R2SxUNvNDQPydB68G9LXjnUNBU18I7VSXACvtuqONA/o3r7oBr5VF/WzqwiWODzOpmpB0zkFloPYCNc633dmThxuMyU0N++tlGwtZkTfzh+8Y1Scba4YrPUvLp0AvxDKnu2Hs71/qc/w2fl9c0Ihz5ilIFEZlxDJNfqX4Zzmij6gxq7DwbbHKPeHdQ2sWv7XTK/HvjDA0FvKFVtGX4w3z4T8MFg7Uqe1lk26MmepSdkcJ8sjsI0yOZfWngYCgYN0L5HqqqCd9JbqCbnQmfRDXxtYEOgMehMD1q8xtiM8J24LcTYZSBEUWxbWrwWSAkmIJcQPJjl9TzfwfBwu5j8OQ7JluZPOw9+1vke01kojvz1mTkPD6T5EumJTi3YdaP563UzKxfy22dlwn5JRx3gNbY7C4/oJkQ9mEz1xo636lnTGhudULavmxUT6v2Q1Hb8A40D5arzQbYI5aufB8kG9oqj7TGFY+lQDuzZN2GA3TW2Qu366VryHMiqDYUjsbeglJbkzNa/d0W7MI9v/x5kO6KgwUa3PufEt7fvUzGNBTL8G8ekh4/ayEjwTkEJx/DGoIb8NtBE4ckM2KOBSY0yEiU6WeH1GQabkb3u6kaXbgIq+B3/t+UuuFHzM6CtBZYjYw/WB4x4Xo1yGALD+IJhO7eG8cYTzmVDPQQb815SrPyoqJ2Dz9FcqxOSymDjcz37NpKJ9Y0phpUNeQR/yaVHa8UPEB0kzwLTpqtj1zDPQKEHdnhxv1iVpGF09gqx4myqVMU3W4jnpDGtaqKSinxmY3AeOsb9vKwvWHXO52MITYOTAQ6fO8IKYimiwLQGVrEGRoEnSHYGLLK0YIGGXLfaatcOMbj8yQcmkbfIip6iRu/qtZnBXD54X8A6Uus7B2CgG9yNGg0k9DLll3yRV2eofFmARP4K8cDYAttaRsuifmcyP5Wf3gduuuIWZZFeINn9ee2+AnPXPU40ukWHyAi5j4Vud2r410QW5856Gtq31wwIEVZ1h8gspZrmiofR3j2Ly1Rj/F/gFt9npHZqRFwMtRf2/mdIEa3RUZnQiv2zx1EdM5magJxMrwJiQ+P+l/ggFAzBTTGLRUg5bQR9wU14/y1Xj6zC5YVqKL2GXNRyzOZzP/kWXNiXVAPJRKOGCULKbVWEuCZeCrCGU8a7PWy2iqC6nr8eCZGKKc1qeHIhCbQmYt0qBGveQIerIs9QempHjLcMFg0ERQxNi1v++uCGjLQgzGgPV5IOEsvuwhVP9SPtx/Dp25jwgsymz67c0goB1RcBkdtWdLcYj9kZNoUWw7R6Jo+7RXLyWbZQ6IrO4Ux5BrmiGfmzeUIBAu6JEisxmaSSy0O36PfiK4VmTmr0kRBwTck8/LqLa8ap+D+GApMkYylH/7MhNkOH1816sZYqmu/i8HnqflJjDwbSLxKQowA6cB1y0GbKTsLa9MWav05l9NjSpUajsPPlKaFra6CQyIjLAoC6CtGKZIaaesofEq3xIVG0C7NHVt4iIEuoqizhJi2JZwZDGp5PXNxwSRrR4M6nSTw8TeiSnvFo=\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 20,\"candidatesTokenCount\": 25,\"totalTokenCount\": 428,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 20}],\"thoughtsTokenCount\": 383},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"uKIdaYWJBMmNvdIP66uD6Ag\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 4.351121s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-2.5-flash/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-2.5-flash/thinking-streaming.yaml
new file mode 100644
index 000000000..bf96a0f08
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-2.5-flash/thinking-streaming.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 550
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence, Italy?"}],"role":"user"}],"generationConfig":{"thinkingConfig":{"includeThoughts":true,"thinkingBudget":128}},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"**Retrieving Weather Data**\\n\\nI've determined that the user is requesting weather information for Florence, Italy. The appropriate course of action is to utilize the 'weather' tool, specifically setting the 'location' parameter to \\\"Florence, Italy\\\". I am now ready to invoke the tool.\\n\\n\\n\",\"thought\": true}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 54,\"totalTokenCount\": 118,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 54}],\"thoughtsTokenCount\": 64},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"pKIdaeGWJZfOvdIPsNOE0Qk\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"functionCall\": {\"name\": \"weather\",\"args\": {\"location\": \"Florence, Italy\"}},\"thoughtSignature\": \"CiQB0e2Kb6BrFiQflb8Sv1fcJ7NAjomD8XzlmWVURMpiVruMgccKYwHR7YpvMnA7YUpMDw7SFo5/T4+Uu75O9TYeVgbxgbO67DG9hZwNJLKKnFjPUTk4KGwgj6xf2mBF48mB00qcBcTNldnnBqvW5d2OJ84gU8nDk03GfVW1err5sbF0ybD2ctjViArnAQHR7YpvHOuUFZzPOv5jO60KyvuXQXD+auw8/ZTTDF+GqgDsx2piCvMdPlQJ4pplwwwq2nAKv8k5Y1rLLcDFbKmaIVMJJwisEbJ5gDLDpDN5IRF6u7BlnXLkATjvKcF5OoDy2Se8IhA5Y26u53m5popZI7v+mswAT49iYnmrBk1UcTsDV7EK2WlebVi6URJwncZbsmfgNCZBDn5LygjopGZC4Md0t/9zC+H109Pv8ByVhhLdq5YCVf5wCzVjvjRSs4/t1MCPFzmxmu+fwQcIY/k+Rxpp706fFrNzCmMOoJCraC83Qb5B7Q==\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0,\"finishMessage\": \"Model generated function call(s).\"}],\"usageMetadata\": {\"promptTokenCount\": 54,\"candidatesTokenCount\": 14,\"totalTokenCount\": 132,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 54}],\"thoughtsTokenCount\": 64},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"pKIdaeGWJZfOvdIPsNOE0Qk\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.213771542s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1286
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence, Italy?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"location":"Florence, Italy"},"id":"1","name":"weather"},"thoughtSignature":"CiQB0e2Kb6BrFiQflb8Sv1fcJ7NAjomD8XzlmWVURMpiVruMgccKYwHR7YpvMnA7YUpMDw7SFo5/T4+Uu75O9TYeVgbxgbO67DG9hZwNJLKKnFjPUTk4KGwgj6xf2mBF48mB00qcBcTNldnnBqvW5d2OJ84gU8nDk03GfVW1err5sbF0ybD2ctjViArnAQHR7YpvHOuUFZzPOv5jO60KyvuXQXD+auw8/ZTTDF+GqgDsx2piCvMdPlQJ4pplwwwq2nAKv8k5Y1rLLcDFbKmaIVMJJwisEbJ5gDLDpDN5IRF6u7BlnXLkATjvKcF5OoDy2Se8IhA5Y26u53m5popZI7v+mswAT49iYnmrBk1UcTsDV7EK2WlebVi6URJwncZbsmfgNCZBDn5LygjopGZC4Md0t/9zC+H109Pv8ByVhhLdq5YCVf5wCzVjvjRSs4/t1MCPFzmxmu+fwQcIY/k+Rxpp706fFrNzCmMOoJCraC83Qb5B7Q=="}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"weather","response":{"result":"40 C"}}}],"role":"user"}],"generationConfig":{"thinkingConfig":{"includeThoughts":true,"thinkingBudget":128}},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"The weather in Florence\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 146,\"candidatesTokenCount\": 4,\"totalTokenCount\": 150,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 146}]},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"pqIdabTFPLDTxN8Pj8DlmQk\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \", Italy is 40 C.\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 146,\"candidatesTokenCount\": 12,\"totalTokenCount\": 158,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 146}]},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"pqIdabTFPLDTxN8Pj8DlmQk\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.488522583s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-2.5-flash/thinking.yaml b/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-2.5-flash/thinking.yaml
new file mode 100644
index 000000000..0eb5727e1
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-2.5-flash/thinking.yaml
@@ -0,0 +1,131 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 550
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence, Italy?"}],"role":"user"}],"generationConfig":{"thinkingConfig":{"includeThoughts":true,"thinkingBudget":128}},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "**Weather Inquiry: Florence, Italy**\n\nOkay, so the user wants to know the weather. Seems straightforward enough. They've specified \"Florence, Italy,\" which is great, because I need a location to work with. Fortunately, I have a \"weather\" tool at my disposal, and it appears it's designed to take a `location` as input. Therefore, my next step is clear: I'll use the \"weather\" tool, feeding it \"Florence, Italy\" as the `location` parameter. That should give me the weather information the user is after.\n",
+ "thought": true
+ },
+ {
+ "functionCall": {
+ "name": "weather",
+ "args": {
+ "location": "Florence, Italy"
+ }
+ },
+ "thoughtSignature": "CvYBAdHtim9qsdgUovUUbgAa9oML5LNXaG6UCnPcGzw1zOO0g3lKC3BMnvd5uNr1Dbu4iv/D1RFKhdpNvKq36C4OgfmARWRVkb6SCFEB2HliZgcq0eH24m1h1Wc3TgGsGNTm4Ppy61sth++CxfYNEZLnw+7xD/VhRMJn5a6/faKS4+MGzsH63NHx0DYdfpFpMytkoCa551Aunb8VOPy9KG2auvUT5KfWqf32mrjbeRhe3ngFDM7gBzYq/1AiVyQVluHSlvmHQ738klIpV7rZelCWzr+QgcPrc+T2MjHoXFtQQ5W24CHqHdW+ViYmcgpQT7QIM/1qCohh"
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0,
+ "finishMessage": "Model generated function call(s)."
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 54,
+ "candidatesTokenCount": 15,
+ "totalTokenCount": 120,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 54
+ }
+ ],
+ "thoughtsTokenCount": 51
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "responseId": "o6Idaab7Kdj9xN8PsaeMoAU"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.776984417s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1118
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence, Italy?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"location":"Florence, Italy"},"id":"1","name":"weather"},"thoughtSignature":"CvYBAdHtim9qsdgUovUUbgAa9oML5LNXaG6UCnPcGzw1zOO0g3lKC3BMnvd5uNr1Dbu4iv/D1RFKhdpNvKq36C4OgfmARWRVkb6SCFEB2HliZgcq0eH24m1h1Wc3TgGsGNTm4Ppy61sth++CxfYNEZLnw+7xD/VhRMJn5a6/faKS4+MGzsH63NHx0DYdfpFpMytkoCa551Aunb8VOPy9KG2auvUT5KfWqf32mrjbeRhe3ngFDM7gBzYq/1AiVyQVluHSlvmHQ738klIpV7rZelCWzr+QgcPrc+T2MjHoXFtQQ5W24CHqHdW+ViYmcgpQT7QIM/1qCohh"}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"weather","response":{"result":"40 C"}}}],"role":"user"}],"generationConfig":{"thinkingConfig":{"includeThoughts":true,"thinkingBudget":128}},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "The weather in Florence, Italy is 40 C."
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 84,
+ "candidatesTokenCount": 12,
+ "totalTokenCount": 96,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 84
+ }
+ ]
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "responseId": "pKIdafytEKa_vdIPwLzvqQk"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 586.682167ms
diff --git a/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-2.5-pro/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-2.5-pro/thinking-streaming.yaml
new file mode 100644
index 000000000..e5122d3c1
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-2.5-pro/thinking-streaming.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 550
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence, Italy?"}],"role":"user"}],"generationConfig":{"thinkingConfig":{"includeThoughts":true,"thinkingBudget":128}},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"**Analyzing Weather Request**\\n\\nI've determined the user is asking for the weather. I've successfully mapped the request to the `weather.get_weather` function. I identified the necessary parameter, `location`, and extracted \\\"Florence, Italy\\\" from the user's input. The core functionality is identified, and the primary data point has been found.\\n\\n\\n\",\"thought\": true}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 54,\"totalTokenCount\": 118,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 54}],\"thoughtsTokenCount\": 64},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"raIdadC2Ley2vdIP_Yq5mQ4\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"functionCall\": {\"name\": \"weather\",\"args\": {\"location\": \"Florence, Italy\"}},\"thoughtSignature\": \"CiIB0e2Kbxjem07JhW18mjM77Q1xAYo6atiTkGnnNaxM6ib5CmcB0e2Kb8IL4bFjiMiDFPUGlfIvUEbRd27l5H14zwW5CEN4jNHSGzGZNldVdmTXMTk+kVlnHncEUaUDL0EuxMc4QFav16fm0Depm9wGyQqGhDSeMQK3QRtAXrimzFT7dCVo3cpA41hwCoABAdHtim9KVkD8CchpZ2W0MEreLCMRm4a4lg5Oien3mEVKAKevqyVEaTH1daHzyHeNLRFqndWwyzYwht6GRlrPjwh56xL1cjZr1RHq+VFop1r/vi44DZpwItRdyydsS/Ya1NTUOAa2ExgLbZmflaNaFAeTfh2mjxhb3jIRjnhu+UAKbwHR7Ypvt9f5xttbSFKScgccrciYxBZaMzYPeYU/Sj7G0VOfQHkWeleXr/1S9L6CK9+OtCElAt+2gPdVTd/p1BzGrPjMwuyCT4d8YZIKOMwoqE75n6cDYN7Mdy3Cd7NtakmsmVztqqn5hA2wCcRnMw==\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0,\"finishMessage\": \"Model generated function call(s).\"}],\"usageMetadata\": {\"promptTokenCount\": 54,\"candidatesTokenCount\": 14,\"totalTokenCount\": 132,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 54}],\"thoughtsTokenCount\": 64},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"raIdadC2Ley2vdIP_Yq5mQ4\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 3.008202292s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1302
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence, Italy?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"location":"Florence, Italy"},"id":"1","name":"weather"},"thoughtSignature":"CiIB0e2Kbxjem07JhW18mjM77Q1xAYo6atiTkGnnNaxM6ib5CmcB0e2Kb8IL4bFjiMiDFPUGlfIvUEbRd27l5H14zwW5CEN4jNHSGzGZNldVdmTXMTk+kVlnHncEUaUDL0EuxMc4QFav16fm0Depm9wGyQqGhDSeMQK3QRtAXrimzFT7dCVo3cpA41hwCoABAdHtim9KVkD8CchpZ2W0MEreLCMRm4a4lg5Oien3mEVKAKevqyVEaTH1daHzyHeNLRFqndWwyzYwht6GRlrPjwh56xL1cjZr1RHq+VFop1r/vi44DZpwItRdyydsS/Ya1NTUOAa2ExgLbZmflaNaFAeTfh2mjxhb3jIRjnhu+UAKbwHR7Ypvt9f5xttbSFKScgccrciYxBZaMzYPeYU/Sj7G0VOfQHkWeleXr/1S9L6CK9+OtCElAt+2gPdVTd/p1BzGrPjMwuyCT4d8YZIKOMwoqE75n6cDYN7Mdy3Cd7NtakmsmVztqqn5hA2wCcRnMw=="}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"weather","response":{"result":"40 C"}}}],"role":"user"}],"generationConfig":{"thinkingConfig":{"includeThoughts":true,"thinkingBudget":128}},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"The weather in Florence\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 146,\"candidatesTokenCount\": 4,\"totalTokenCount\": 150,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 146}]},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"sKIdae6vLf_WvdIPm53psAk\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \", Italy is 40 C. \\n\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 146,\"candidatesTokenCount\": 12,\"totalTokenCount\": 158,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 146}]},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"sKIdae6vLf_WvdIPm53psAk\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.696688208s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-2.5-pro/thinking.yaml b/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-2.5-pro/thinking.yaml
new file mode 100644
index 000000000..1237887cf
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-2.5-pro/thinking.yaml
@@ -0,0 +1,131 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 550
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence, Italy?"}],"role":"user"}],"generationConfig":{"thinkingConfig":{"includeThoughts":true,"thinkingBudget":128}},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "**Getting the Weather in Florence**\n\nOkay, so I see the user wants to know the weather in Florence, Italy. That's straightforward; that query directly corresponds to my `weather.get_weather` function. It's pretty clear-cut, the function takes a `location` parameter, and in this case, that `location` is simply \"Florence, Italy\". Nothing complicated here, I can just set that parameter and move on.\n",
+ "thought": true
+ },
+ {
+ "functionCall": {
+ "name": "weather",
+ "args": {
+ "location": "Florence, Italy"
+ }
+ },
+ "thoughtSignature": "CpwCAdHtim+0FmI+WFq9+osYttd0V3wq5L6xpmfD+s3Xy+iz1L6F5MmUgDo3Vop462ydmq46DgqFSLYj33RAcxmXMnfJMnqdDbLkR00eT6FtPNKk1HxBIDg+d8nxH5LBRnQ4+/Py4nOa4oMiTfNaOuMpZZnIyJBRLFSOw0ZQftvmXoKCB/hZEW6dYve3wxGH+o4BZ/sdxO/3IdPhk2eRlcieDEVN/F4Fg1xAmdc/60inB/SsuSIMRRKHW/48nlCOwlJbbTRI9FIhtqLkDwjXMMWxwovwhstRb4+frvLsOIsBNQk+q5MByNI+waAOxhSVVvHChLh9vQTM4xZ0g14GGZ6SbLz+ujRWdPYjN1ON25uMX00ZTwM2S5K8IZUeJsM="
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0,
+ "finishMessage": "Model generated function call(s)."
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 54,
+ "candidatesTokenCount": 15,
+ "totalTokenCount": 135,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 54
+ }
+ ],
+ "thoughtsTokenCount": 66
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "responseId": "qqIdaZ73A_ClvdIPvJaP0Ak"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 3.080074125s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1170
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence, Italy?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"location":"Florence, Italy"},"id":"1","name":"weather"},"thoughtSignature":"CpwCAdHtim+0FmI+WFq9+osYttd0V3wq5L6xpmfD+s3Xy+iz1L6F5MmUgDo3Vop462ydmq46DgqFSLYj33RAcxmXMnfJMnqdDbLkR00eT6FtPNKk1HxBIDg+d8nxH5LBRnQ4+/Py4nOa4oMiTfNaOuMpZZnIyJBRLFSOw0ZQftvmXoKCB/hZEW6dYve3wxGH+o4BZ/sdxO/3IdPhk2eRlcieDEVN/F4Fg1xAmdc/60inB/SsuSIMRRKHW/48nlCOwlJbbTRI9FIhtqLkDwjXMMWxwovwhstRb4+frvLsOIsBNQk+q5MByNI+waAOxhSVVvHChLh9vQTM4xZ0g14GGZ6SbLz+ujRWdPYjN1ON25uMX00ZTwM2S5K8IZUeJsM="}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"weather","response":{"result":"40 C"}}}],"role":"user"}],"generationConfig":{"thinkingConfig":{"includeThoughts":true,"thinkingBudget":128}},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "It's 40 C in Florence, Italy. \n"
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 84,
+ "candidatesTokenCount": 12,
+ "totalTokenCount": 96,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 84
+ }
+ ]
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "responseId": "rKIdaY5egY690g_byfO5CQ"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.95741725s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-3-pro-preview/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-3-pro-preview/thinking-streaming.yaml
new file mode 100644
index 000000000..6e9c8bd55
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-3-pro-preview/thinking-streaming.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 550
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence, Italy?"}],"role":"user"}],"generationConfig":{"thinkingConfig":{"includeThoughts":true,"thinkingBudget":128}},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"**Examining the Query**\\n\\nI'm currently analyzing the incoming request. The user is clearly seeking current weather information. My primary focus is pinpointing the specific locationāFlorence, Italyāwhich is crucial for the function call. I need to formulate the right parameters to obtain the correct weather data.\\n\\n\\n\",\"thought\": true}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 65,\"totalTokenCount\": 65,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 65}]},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"n6IdafKCLorkvdIPipOBkQk\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"**Exploring Tool Options**\\n\\nI've discovered a tool, aptly named \\\"default\\\\_api:weather,\\\" which is ideal for this task. It seems perfectly suited, with its description explicitly stating its capability to retrieve weather details based on location. I'm now certain this is the appropriate API call to acquire the necessary information. I'm moving forward with confidence.\\n\\n\\n\",\"thought\": true}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 65,\"totalTokenCount\": 65,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 65}]},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"n6IdafKCLorkvdIPipOBkQk\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"functionCall\": {\"name\": \"weather\",\"args\": {\"location\": \"Florence, Italy\"}},\"thoughtSignature\": \"EoMECoAEAdHtim81mSx3N5M3zd8oz+3yIyyUSy0Gz1XbUZ0/o+D/FVqMu7H+cuRdFB7jIOareNRWH5VZs2W64dxNI6YnvG9VdmYQyucoUMDLOrrEMFosx5QgJRzpKTJ9Kh6QoTZrlDg9WC0Z7JXPc75LN7YR1Y+Sto3FKTAuJ7l93u7Yhfc5Q9q1zi7FK5hELlkQD5Z8/ENCv0ouCmWPi3QK0nnl4t2SxzdP455ujbh8klcm+5F705VhNvD9o55MX7DUx0mIExhCvkIWMjfx0tMmC9mlHH6KuqwBjFzaoUF6l8S0Xb50NYA1t63F/G6sb+OUw3m/5uoxpyHrFihKehsBkOpI7sBtbMgcAOmZHDkp+MxBK7fbBOg8zLCLKP9A64d2Qsx0oEwUTiGDNVdKLu4i6SQc/p/PNUoWG4RQ4oGOxXM/1kVlvws1aRNPZBk7uTPmjVXg3dzXlX1bin4GomZy2aEt5sPzv6kCc0BCZhh05y7SYZGhA0J1uyKdrun5SLaG8DtIhS2Jb+RJBON3ubIUaBZDUa4RVS/QnNPBpAXEDI7q5HBKiz2tuKstpMDsP48rbtR2rh4sG/gnVVDMESMgyJtI291plYuBsZS7+fUuxr8y+9pu4BxvuZwUXuKOSfOZe815ILhKyDNCdcp+1QSuBy6XUrp5DLL1ucH5Hu4tk+bnShA=\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 65,\"candidatesTokenCount\": 16,\"totalTokenCount\": 185,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 65}],\"thoughtsTokenCount\": 104},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"n6IdafKCLorkvdIPipOBkQk\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 65,\"candidatesTokenCount\": 16,\"totalTokenCount\": 185,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 65}],\"thoughtsTokenCount\": 104},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"n6IdafKCLorkvdIPipOBkQk\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.532721041s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1478
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence, Italy?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"location":"Florence, Italy"},"id":"1","name":"weather"},"thoughtSignature":"EoMECoAEAdHtim81mSx3N5M3zd8oz+3yIyyUSy0Gz1XbUZ0/o+D/FVqMu7H+cuRdFB7jIOareNRWH5VZs2W64dxNI6YnvG9VdmYQyucoUMDLOrrEMFosx5QgJRzpKTJ9Kh6QoTZrlDg9WC0Z7JXPc75LN7YR1Y+Sto3FKTAuJ7l93u7Yhfc5Q9q1zi7FK5hELlkQD5Z8/ENCv0ouCmWPi3QK0nnl4t2SxzdP455ujbh8klcm+5F705VhNvD9o55MX7DUx0mIExhCvkIWMjfx0tMmC9mlHH6KuqwBjFzaoUF6l8S0Xb50NYA1t63F/G6sb+OUw3m/5uoxpyHrFihKehsBkOpI7sBtbMgcAOmZHDkp+MxBK7fbBOg8zLCLKP9A64d2Qsx0oEwUTiGDNVdKLu4i6SQc/p/PNUoWG4RQ4oGOxXM/1kVlvws1aRNPZBk7uTPmjVXg3dzXlX1bin4GomZy2aEt5sPzv6kCc0BCZhh05y7SYZGhA0J1uyKdrun5SLaG8DtIhS2Jb+RJBON3ubIUaBZDUa4RVS/QnNPBpAXEDI7q5HBKiz2tuKstpMDsP48rbtR2rh4sG/gnVVDMESMgyJtI291plYuBsZS7+fUuxr8y+9pu4BxvuZwUXuKOSfOZe815ILhKyDNCdcp+1QSuBy6XUrp5DLL1ucH5Hu4tk+bnShA="}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"weather","response":{"result":"40 C"}}}],"role":"user"}],"generationConfig":{"thinkingConfig":{"includeThoughts":true,"thinkingBudget":128}},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"It\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 95,\"candidatesTokenCount\": 1,\"totalTokenCount\": 96,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 95}]},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"oaIdaciSM6HXxN8Ph5ic0Ak\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"'s currently 40 degrees Celsius in Florence, Italy.\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 95,\"candidatesTokenCount\": 14,\"totalTokenCount\": 109,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 95}]},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"oaIdaciSM6HXxN8Ph5ic0Ak\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 197,\"candidatesTokenCount\": 14,\"totalTokenCount\": 211,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 197}]},\"modelVersion\": \"gemini-3-pro-preview\",\"responseId\": \"oaIdaciSM6HXxN8Ph5ic0Ak\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.537615041s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-3-pro-preview/thinking.yaml b/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-3-pro-preview/thinking.yaml
new file mode 100644
index 000000000..8d6a343f9
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleThinking/gemini-3-pro-preview/thinking.yaml
@@ -0,0 +1,131 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 550
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence, Italy?"}],"role":"user"}],"generationConfig":{"thinkingConfig":{"includeThoughts":true,"thinkingBudget":128}},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "**Breaking Down the Weather Query**\n\nOkay, here's what I'm processing. A user is asking about the weather in Florence, Italy. That's straightforward enough - they want current weather data. Looking at my toolset, I see the `weather` tool is perfect for this. It's explicitly designed for retrieving weather information based on a location. Easy. This is a classic example of intent recognition and tool selection. My next step would be to formulate the `weather` function call with the correct parameters, specifically the location, \"Florence, Italy\". I'm ready to get this user the information they need.\n\n\n",
+ "thought": true
+ },
+ {
+ "functionCall": {
+ "name": "weather",
+ "args": {
+ "location": "Florence, Italy"
+ }
+ },
+ "thoughtSignature": "EtMDCtADAdHtim/Qznjl3jYdbqtczyFkf1sarL7CYPmwkwMTU8qifm7AQe1i21NWqWvbSGT+KG/NkCBhcC0Zc8MusHqgFm2Iw+2TP0Ckp8nL5k+1G7jffxPRKsXcyq/6jvRtGvcxb199vZTNapt2/vYas7tEOZahNr/Xiuic7yVEcEEQD8Vdsp9qgRy8qu4RO1nc8Q5cnbd8fOEKfjusde2ehpTA47PUNhhIWlLBEGeMOowAoaEf9/W7cMxlg21omQYaYiIVgvI1qi2U/4nSOKDBlTA2N0LDuygPTtRsz2ZMwJGC8CIrrCW0apY1X2QcgO+s/9tNurJp/D9tiIFnwRXT8q7V90nAng9dSqHrChr2jvr4n3j5wgbvHnqLJouCKR8ME+leQZUHefdJyHeXNSjv9Rzs7cqiaUgWR7Rn11BQld3Q/myVqq7/r0LI/IchztYQVKDvE0XXbc0o8x4cfQTmtdlSwcAQxE5OG6sLNoRPAJmPfkwlppeHwNGG7ntkCKX/nG/o40w2OyFwk6WnkyNhnqTiA5knDyP51fnOiwKhFYxtDa7f2WdUPsILiJjqT7hDjtYTCnYvuWgTvqkaRtfLWES9QIVVZP63zK6PDFQLtLp8kd0="
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0,
+ "finishMessage": "Model generated function call(s)."
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 65,
+ "candidatesTokenCount": 16,
+ "totalTokenCount": 189,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 65
+ }
+ ],
+ "thoughtsTokenCount": 108
+ },
+ "modelVersion": "gemini-3-pro-preview",
+ "responseId": "mqIdabO3C5S3vdIPuPm34Ak"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 3.163927334s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1414
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"What's the weather in Florence, Italy?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"location":"Florence, Italy"},"id":"1","name":"weather"},"thoughtSignature":"EtMDCtADAdHtim/Qznjl3jYdbqtczyFkf1sarL7CYPmwkwMTU8qifm7AQe1i21NWqWvbSGT+KG/NkCBhcC0Zc8MusHqgFm2Iw+2TP0Ckp8nL5k+1G7jffxPRKsXcyq/6jvRtGvcxb199vZTNapt2/vYas7tEOZahNr/Xiuic7yVEcEEQD8Vdsp9qgRy8qu4RO1nc8Q5cnbd8fOEKfjusde2ehpTA47PUNhhIWlLBEGeMOowAoaEf9/W7cMxlg21omQYaYiIVgvI1qi2U/4nSOKDBlTA2N0LDuygPTtRsz2ZMwJGC8CIrrCW0apY1X2QcgO+s/9tNurJp/D9tiIFnwRXT8q7V90nAng9dSqHrChr2jvr4n3j5wgbvHnqLJouCKR8ME+leQZUHefdJyHeXNSjv9Rzs7cqiaUgWR7Rn11BQld3Q/myVqq7/r0LI/IchztYQVKDvE0XXbc0o8x4cfQTmtdlSwcAQxE5OG6sLNoRPAJmPfkwlppeHwNGG7ntkCKX/nG/o40w2OyFwk6WnkyNhnqTiA5knDyP51fnOiwKhFYxtDa7f2WdUPsILiJjqT7hDjtYTCnYvuWgTvqkaRtfLWES9QIVVZP63zK6PDFQLtLp8kd0="}],"role":"model"},{"parts":[{"functionResponse":{"id":"1","name":"weather","response":{"result":"40 C"}}}],"role":"user"}],"generationConfig":{"thinkingConfig":{"includeThoughts":true,"thinkingBudget":128}},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"},"toolConfig":{"functionCallingConfig":{"mode":"AUTO"}},"tools":[{"functionDeclarations":[{"description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"STRING"}},"required":["location"],"type":"OBJECT"}}]}]}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.4
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "It's currently 40°C (104°F) in Florence, Italy. That is quite hot!"
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 201,
+ "candidatesTokenCount": 26,
+ "totalTokenCount": 227,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 201
+ }
+ ]
+ },
+ "modelVersion": "gemini-3-pro-preview",
+ "responseId": "naIdabjfC4HhvdIPo9CWoAk"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 3.0175995s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-claude-3-7-sonnet/complex_object.yaml b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-claude-3-7-sonnet/complex_object.yaml
new file mode 100644
index 000000000..2c5dcb933
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-claude-3-7-sonnet/complex_object.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 978
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","type":"text"}],"role":"user"}],"tool_choice":{"name":"Book","disable_parallel_tool_use":false,"type":"tool"},"tools":[{"input_schema":{"properties":{"author":{"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"name":"Book","description":"A book with title, author, genres, and publication year"}],"anthropic_version":"vertex-2023-10-16"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://us-east5-aiplatform.googleapis.com/v1/projects/fantasy-playground-472418/locations/us-east5/publishers/anthropic/models/claude-3-7-sonnet@20250219:rawPredict
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_vrtx_01UAjss8kpXQotMqUWtjP8Vd","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_vrtx_01UqmeUWH5fBpvtZE1jx4knQ","name":"Book","input":{"title":"The Lord of the Rings","author":{"name":"J.R.R. Tolkien","nationality":"British"},"genres":["Fantasy","Adventure","Epic","High fantasy"],"published_year":1954}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":548,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":132}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.867918541s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-claude-3-7-sonnet/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-claude-3-7-sonnet/complex_object_streaming.yaml
new file mode 100644
index 000000000..f4ef60e3a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-claude-3-7-sonnet/complex_object_streaming.yaml
@@ -0,0 +1,132 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 992
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","type":"text"}],"role":"user"}],"tool_choice":{"name":"Book","disable_parallel_tool_use":false,"type":"tool"},"tools":[{"input_schema":{"properties":{"author":{"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"name":"Book","description":"A book with title, author, genres, and publication year"}],"stream":true,"anthropic_version":"vertex-2023-10-16"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://us-east5-aiplatform.googleapis.com/v1/projects/fantasy-playground-472418/locations/us-east5/publishers/anthropic/models/claude-3-7-sonnet@20250219:streamRawPredict
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"model":"claude-3-7-sonnet-20250219","id":"msg_vrtx_01JiiYx8JQZEW8hLLjVmFa6C","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":548,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":15}} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"tool_use","id":"toolu_vrtx_01TpniKAvXfPprSuYGgYUUSx","name":"Book","input":{}} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"{\"title\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":": \"T"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"he "} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"Lord "} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"of the Rings"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":", \"au"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"thor\": {\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"name\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":":\"J.R"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":".R. Tolkien"}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"\","} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"\"nationalit"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"y\":\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"British\"}"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":", \"genre"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"s\": [\"Fantas"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"y\",\"A"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"dventure\",\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"Epic\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"]"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":", \"publishe"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"d_yea"}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"r\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":": 195"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"4}"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"output_tokens":119} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 952.687083ms
diff --git a/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-claude-3-7-sonnet/simple_object.yaml b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-claude-3-7-sonnet/simple_object.yaml
new file mode 100644
index 000000000..edef4a4e3
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-claude-3-7-sonnet/simple_object.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 642
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris.","type":"text"}],"role":"user"}],"tool_choice":{"name":"Person","disable_parallel_tool_use":false,"type":"tool"},"tools":[{"input_schema":{"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"},"name":"Person","description":"A person with name, age, and city"}],"anthropic_version":"vertex-2023-10-16"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://us-east5-aiplatform.googleapis.com/v1/projects/fantasy-playground-472418/locations/us-east5/publishers/anthropic/models/claude-3-7-sonnet@20250219:rawPredict
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_vrtx_014VLsXeDXtuC84Nx9V4pBdW","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_vrtx_01TaBaQU6GZpxjApVgvzLfev","name":"Person","input":{"name":"Alice","age":30,"city":"Paris"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":453,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":67}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.818802583s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-claude-3-7-sonnet/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-claude-3-7-sonnet/simple_object_streaming.yaml
new file mode 100644
index 000000000..86dfcc838
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-claude-3-7-sonnet/simple_object_streaming.yaml
@@ -0,0 +1,81 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 656
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris.","type":"text"}],"role":"user"}],"tool_choice":{"name":"Person","disable_parallel_tool_use":false,"type":"tool"},"tools":[{"input_schema":{"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"},"name":"Person","description":"A person with name, age, and city"}],"stream":true,"anthropic_version":"vertex-2023-10-16"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.14.0
+ url: https://us-east5-aiplatform.googleapis.com/v1/projects/fantasy-playground-472418/locations/us-east5/publishers/anthropic/models/claude-3-7-sonnet@20250219:streamRawPredict
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"model":"claude-3-7-sonnet-20250219","id":"msg_vrtx_01XdrdQzn2BFw8pob1JJCRnX","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":453,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":11}}}
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"tool_use","id":"toolu_vrtx_01Y5BDgK5DcxEvwThJWL5Pix","name":"Person","input":{}} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"{\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"name\":"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":" \"Alice\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":", \"age\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":": 30"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":", \"city\""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":": \"P"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"ari"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"s\"}"} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"output_tokens":67} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.471510916s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-flash/complex_object.yaml b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-flash/complex_object.yaml
new file mode 100644
index 000000000..2f6f90712
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-flash/complex_object.yaml
@@ -0,0 +1,70 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 817
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about 'The Lord of the Rings' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954)."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"author":{"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"responseMimeType":"application/json"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.0
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "role": "model",
+ "parts": [
+ {
+ "text": "{\n \"title\": \"The Lord of the Rings\",\n \"author\": {\n \"name\": \"J.R.R. Tolkien\",\n \"nationality\": \"British\"\n },\n \"genres\": [\n \"fantasy\",\n \"adventure\"\n ],\n \"published_year\": 1954\n}"
+ }
+ ]
+ },
+ "finishReason": "STOP",
+ "avgLogprobs": -0.45047834322050018
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 37,
+ "candidatesTokenCount": 77,
+ "totalTokenCount": 246,
+ "trafficType": "ON_DEMAND",
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 37
+ }
+ ],
+ "candidatesTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 77
+ }
+ ],
+ "thoughtsTokenCount": 132
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "createTime": "2025-11-10T12:36:25.122147Z",
+ "responseId": "SdwRaaO6B9fzptQPk5W9sQ8"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.655407625s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-flash/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-flash/complex_object_streaming.yaml
new file mode 100644
index 000000000..696814b86
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-flash/complex_object_streaming.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 817
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about 'The Lord of the Rings' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954)."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"author":{"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"responseMimeType":"application/json"}}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.0
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-flash:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \"{\\n \\\"title\\\": \\\"The Lord of the Rings\\\",\\n \\\"author\\\": {\\n \"}]}}],\"usageMetadata\": {\"trafficType\": \"ON_DEMAND\"},\"modelVersion\": \"gemini-2.5-flash\",\"createTime\": \"2025-11-10T12:36:26.936156Z\",\"responseId\": \"StwRadyROZ3qptQPg8OiiQU\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \"\\\"name\\\": \\\"J.R.R. Tolkien\\\",\\n \\\"nationality\\\": \\\"British\\\"\\n },\\n \\\"genres\\\": [\\n \\\"fantasy\\\",\\n \\\"adventure\\\"\\n ],\\n \\\"published_year\"}]}}],\"usageMetadata\": {\"trafficType\": \"ON_DEMAND\"},\"modelVersion\": \"gemini-2.5-flash\",\"createTime\": \"2025-11-10T12:36:26.936156Z\",\"responseId\": \"StwRadyROZ3qptQPg8OiiQU\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \"\\\": 1954\\n}\"}]},\"finishReason\": \"STOP\"}],\"usageMetadata\": {\"promptTokenCount\": 37,\"candidatesTokenCount\": 77,\"totalTokenCount\": 165,\"trafficType\": \"ON_DEMAND\",\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 37}],\"candidatesTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 77}],\"thoughtsTokenCount\": 51},\"modelVersion\": \"gemini-2.5-flash\",\"createTime\": \"2025-11-10T12:36:26.936156Z\",\"responseId\": \"StwRadyROZ3qptQPg8OiiQU\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 997.700625ms
diff --git a/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-flash/simple_object.yaml b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-flash/simple_object.yaml
new file mode 100644
index 000000000..ad3fdc501
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-flash/simple_object.yaml
@@ -0,0 +1,70 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 499
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"responseMimeType":"application/json"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.0
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "role": "model",
+ "parts": [
+ {
+ "text": "{\"name\": \"Alice\", \"age\": 30, \"city\": \"Paris\"}"
+ }
+ ]
+ },
+ "finishReason": "STOP",
+ "avgLogprobs": -0.57498173964651011
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 19,
+ "candidatesTokenCount": 19,
+ "totalTokenCount": 83,
+ "trafficType": "ON_DEMAND",
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 19
+ }
+ ],
+ "candidatesTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 19
+ }
+ ],
+ "thoughtsTokenCount": 45
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "createTime": "2025-11-10T12:36:22.649878Z",
+ "responseId": "RtwRaZbVJ-zzptQPvOrxqQ8"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.886921167s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-flash/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-flash/simple_object_streaming.yaml
new file mode 100644
index 000000000..9f21d8981
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-flash/simple_object_streaming.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 499
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"responseMimeType":"application/json"}}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.0
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-flash:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \"{\\n \\\"name\\\": \\\"Alice\\\",\\n \\\"age\\\": 30,\\n \\\"city\\\": \\\"Paris\\\"\\n}\"}]},\"finishReason\": \"STOP\"}],\"usageMetadata\": {\"promptTokenCount\": 19,\"candidatesTokenCount\": 28,\"totalTokenCount\": 124,\"trafficType\": \"ON_DEMAND\",\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 19}],\"candidatesTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 28}],\"thoughtsTokenCount\": 77},\"modelVersion\": \"gemini-2.5-flash\",\"createTime\": \"2025-11-10T12:36:23.898113Z\",\"responseId\": \"R9wRacHoNpyYw8cPz9-4-QY\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.064075083s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-pro/complex_object.yaml b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-pro/complex_object.yaml
new file mode 100644
index 000000000..13a19b284
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-pro/complex_object.yaml
@@ -0,0 +1,70 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 817
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about 'The Lord of the Rings' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954)."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"author":{"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"responseMimeType":"application/json"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.0
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "role": "model",
+ "parts": [
+ {
+ "text": "{\n \"title\": \"The Lord of the Rings\",\n \"author\": {\n \"name\": \"J.R.R. Tolkien\",\n \"nationality\": \"British\"\n },\n \"genres\": [\n \"Fantasy\",\n \"Adventure\"\n ],\n \"published_year\": 1954\n}"
+ }
+ ]
+ },
+ "finishReason": "STOP",
+ "avgLogprobs": -0.67830568784243106
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 37,
+ "candidatesTokenCount": 77,
+ "totalTokenCount": 514,
+ "trafficType": "ON_DEMAND",
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 37
+ }
+ ],
+ "candidatesTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 77
+ }
+ ],
+ "thoughtsTokenCount": 400
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "createTime": "2025-11-10T12:36:32.031653Z",
+ "responseId": "UNwRaaX3AZ3qptQPg8OiiQU"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 5.257772958s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-pro/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-pro/complex_object_streaming.yaml
new file mode 100644
index 000000000..cbbd24b46
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-pro/complex_object_streaming.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 817
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about 'The Lord of the Rings' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954)."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"author":{"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"responseMimeType":"application/json"}}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.0
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \"{\\n \\\"title\\\": \\\"The Lord of the Rings\\\",\\n \\\"author\\\": {\\n \\\"name\\\": \\\"J.R.R. Tolkien\\\",\\n \\\"nationality\\\": \\\"British\\\"\\n },\\n \\\"genres\\\": [\\n \\\"Fantasy\"}]}}],\"usageMetadata\": {\"trafficType\": \"ON_DEMAND\"},\"modelVersion\": \"gemini-2.5-pro\",\"createTime\": \"2025-11-10T12:36:37.457838Z\",\"responseId\": \"VdwRae74G-zzptQPvOrxqQ8\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \"\\\",\\n \\\"Adventure\\\"\\n ],\\n \\\"published_year\\\": 1954\\n}\"}]},\"finishReason\": \"STOP\"}],\"usageMetadata\": {\"promptTokenCount\": 37,\"candidatesTokenCount\": 77,\"totalTokenCount\": 467,\"trafficType\": \"ON_DEMAND\",\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 37}],\"candidatesTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 77}],\"thoughtsTokenCount\": 353},\"modelVersion\": \"gemini-2.5-pro\",\"createTime\": \"2025-11-10T12:36:37.457838Z\",\"responseId\": \"VdwRae74G-zzptQPvOrxqQ8\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 3.749448334s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-pro/simple_object.yaml b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-pro/simple_object.yaml
new file mode 100644
index 000000000..c13ec37b7
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-pro/simple_object.yaml
@@ -0,0 +1,70 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 499
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"responseMimeType":"application/json"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.0
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "role": "model",
+ "parts": [
+ {
+ "text": "{\n \"name\": \"Alice\",\n \"age\": 30,\n \"city\": \"Paris\"\n}"
+ }
+ ]
+ },
+ "finishReason": "STOP",
+ "avgLogprobs": -0.58463580267769955
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 19,
+ "candidatesTokenCount": 28,
+ "totalTokenCount": 102,
+ "trafficType": "ON_DEMAND",
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 19
+ }
+ ],
+ "candidatesTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 28
+ }
+ ],
+ "thoughtsTokenCount": 55
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "createTime": "2025-11-10T12:36:28.270555Z",
+ "responseId": "TNwRadvBENLK5OMPoK7I0AI"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.459651375s
diff --git a/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-pro/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-pro/simple_object_streaming.yaml
new file mode 100644
index 000000000..5fdc60544
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestGoogleVertexObjectGeneration/vertex-gemini-2-5-pro/simple_object_streaming.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 499
+ host: us-east5-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris."}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000,"responseJsonSchema":{"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"responseMimeType":"application/json"}}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.34.0 gl-go/go1.25.0
+ url: https://us-east5-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-east5/publishers/google/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"role\": \"model\",\"parts\": [{\"text\": \"{\\n \\\"name\\\": \\\"Alice\\\",\\n \\\"age\\\": 30,\\n \\\"city\\\": \\\"Paris\\\"\\n}\"}]},\"finishReason\": \"STOP\"}],\"usageMetadata\": {\"promptTokenCount\": 19,\"candidatesTokenCount\": 28,\"totalTokenCount\": 209,\"trafficType\": \"ON_DEMAND\",\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 19}],\"candidatesTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 28}],\"thoughtsTokenCount\": 162},\"modelVersion\": \"gemini-2.5-pro\",\"createTime\": \"2025-11-10T12:36:29.889263Z\",\"responseId\": \"TdwRaa-jNvWAptQPkJGMwQ8\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.9909835s
diff --git a/internal/fantasy/providertests/testdata/TestImageUploadAgent/anthropic-claude-sonnet-4.yaml b/internal/fantasy/providertests/testdata/TestImageUploadAgent/anthropic-claude-sonnet-4.yaml
new file mode 100644
index 000000000..81af3f96b
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestImageUploadAgent/anthropic-claude-sonnet-4.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 4126
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Describe the image briefly in English.","type":"text"},{"source":{"data":"iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAK+0lEQVR4nJSZa48cR9XH/1V9m/us1+td39b7rO04myixkzh5EsdPnhgibsZCCZAoEIGExCskxFfgKyA+AbwAJCQEiPAiMpeAkgDBsdeJQyI77CWxs2vvfWem73VQVXX39Ez3rk2rNJrtnq761f+cOudUrfm95wmDFwOGb+1wJb9kO/+i0NE9dm7u3tVuvbB7GIANd3qPE+a7P96FqeQOG7jP8l/YrqIWOr4LVul7bGjsoSFTvmxK9N/A6R+XGHF3pgEJs7GLg5Gkp9xQ+bfk051NwfJYuzujfMpKEEs+825EBWjKzWeH8QgwM5rdnHHIu4dQlFk1tOwt644KNIOzl2/tMKp576tpQDCWc04G4ukXRcNE8qUPx0ooaWcb3c23cvpTTqREHoUCI9cIiEGx/IQYIGMcjCQu5eCSqRbISrD6P2MFvlQk0kBcdWACdtoEEKgWApH6U8gfWoDN5c+DGIGA0MSZEQtkO4fTHZj6OmkmC3CAOtg4pmbWVlfq2/MO2wQ8UAAWgQtJW+FoVLB/fzy/YLgB3EiSkSJjVGLNciOyoZWfw6K84WwwB9QAO4hnX5h98tAiC+2fXDyzdLnF1mEwaThbwGGoW3jgWHz6nPfrn9bXtmRnvQikNCt17rJwOsjEMtfmOZG04RygBuzFiWfn7j+0wBFWre7L5962j0bUAqvCcmSr13BwL578vHtwJnj4oWikiZqNiqF6ZkPZILmMJ2Z+OMQ08D233OSnFknbzgaqQBv1B3vnzl5qsaCK2ARVLb/SwvVb4whgEUYqeOKR8P+/3BufjhjH4ZlwpEHdTb65xUMhfU87WX50NqxW0Z+KTJZszAEq0qWwD4+fudbmvgNhaA+HeHzyxqGZTWojrkpFzQpxK+2Vk2HBtHNzLmQIAnh5jspeyDzJzInkgJSbYxRTp2+eGLtVQ2RD8CQYCM7CC6dn2QSiOtYJb161X/1Fc3neEgJv/ar52m+rN+aNIFZSFVVgQ0ZkuzJZYHrRaZ0awB407++eP/OPPdyvQCis/tV0PFGx5+6MUog4hhciWjeaNfH6nyprXXgBfIF45/Ri7sjEckwqJpGdc/M22se6z//f3/abXUu5VKH6is8df295q/XhlXF/A5su3l0y1v9cXQngEwKGKEtWrADHSgNExqQXnaNcu6poakAT1Yng1IOLZ49+0DBcDsH6KSYfHAVnwYuPvvXHxsN/n532VljUxca6QcoZojBZ1ETlKZLJornUfJpJ22sv2AQmjmz+z+HVo/tvT4/ctnnAEgcvtURec2PdHbm0OH3to4Mbt6q0Cr4OdBC7oFDmKBYXEmgJlg7lHKSjZR18Sjx94foTRxfbdheIlTaD2a6soKdhb+BE5lJn9PJHU/98Y5LmOW2DfJmgKEZxgmZpNKMUzrbxzKm1ysyiB0/7NRI3olKdNja6IyN1JOmOEVEURpZtyrcYHWjeOfDIWrvae+3nD5ieZOIqp8c07GHlUV5bugK8UMUX77SX4tos7BuwbsPoyURXnjGWPl0/eeT7uW7otVff+e43ftRXUEpD674DBoOjamFynxitwjKGNwE8r3vfAASHcK6KZxxUV6ynZo9vcmuOW/OwlmBugLtlcEEQeV6Yv+P2/F7X152SKiluBY0rVyd5IOvP8Ra++rL79JNh25EJNDO7CqdlWzkbeMzB+aaS2MOJyxPHPjnkwlzm5hKMVRhb4D3wQD3X5a/1/rGa0RyfaOe7arVr7ZG6cXOcr7VjsA7Mi7MPBbcsFshS8fBkNHYoOn4yaDYFG/RNk4atJ9ffCQsv7lFKCsQhaBtn3zh++8LWdn19jQsuyJCVhJwVQZgg0604bz66/znv6sKPZT9dWXJRHZ/9wsnPfO6k8/v7o71b22fef+/O4bnLB1hHVmNhiKvXTBbXF/9tLq8hHnR5FeVzXm8CR0x8Zx9qyt6xqmQEA4v5aNC6Pr0s0ysji2RwNdJEwKwoum8+Hl9jKplZb6P2M4QnQXXGGAumPvUO39mC87u//G8wb7FtwJezjQIsL/Gtniy/qLQM1BHQIOzj+NZeNA15U+gaN4aIEHsYnWsePX5obnI+UBasQzhqJRtqdcfNXhYSgrMInlLUurJ3ogjG1Y+nOgs19KRUIpLmDwRCFR2IhrckPHN3DrQZXhnDuK2YdCghCSdixBEiF/f9axIwhQyBLJILg2FgnSQxTTaD6TvpU+P961PogAW5Ml8klWBxYXP9ElcFwdf3YLqSMGVjxKSaQBTBuVNtdJp6u8CU9fKHDIqDiaQhNyJzw8raUgsqfso55eTJm4/l4xZTGe9LLZyqp0w6s2ggtbBDQiiknza2GlxiJTqnW3+WzCH5lENrPqUo2/DqcFX8FHKZGEMBs3BwIrevFeBsDc+25CCC9aO4HiZKsQKS1Yjh24ZgmbOnk6SMTKHokEhceR4AL7QplLAGwVKxNObwmOy/9OIV4KSDC6OymwHbqfwXqwokVPurQC4gkOA8XYM8Z74YLJSewwP5qRtPLcbi2ID6ZjLULJyaifZUUTdUFB0SSmMds/DSmHycZTuRNikVS4ACBp9B5bGkeFZqMSWS3HcF4D4MT2Yn2VxwTzbJFyPp1yAZd6bHcP6l3mMPRa2q3KixsmMc85v75CYkO4oRrA8kmZjkyJg8IDREisWUIzIBHoL5qmkOApmyaqSKbNJJBBKs+ybjr3yt2xqLn3ulU23VLl60ZdAqGNFsq8gV56XKbKek8jMmhp68SVbCxGLpwdJ2XfBNmOswelyWTwBZEFWIlhAtiBbgx4YOV3MLxh9+2Tj/7a0rF2tvv2UHUa4SzIUTWdiINEFqqaKcVFInrrCYDIQ9uR65NlwsEzZ3YazD/NjdM7cysbrVCsio1Hpjo6sTIytdHmzyuCnEOGitU4ULEaAT4NoNXv9N7d137NVttYkti1umyMVA7eYRVzrlmQBXYwn4rhPACFT1tglzYXP8o8UjK7fbQYhIqCnx5pwxYTbCwwdvT00s+bWtrqCPP9gvK9IAPV9u81//qx1FMufEIt3sD54dsugHpEUSLBWJS6CAw+PwDLiqdSx0HGxX0Z30nXPvmTzeWB399JMDmyt1P5Q5JCREJF8XuhmyviUT1bq//yYasw42tG8m0YzyIZ6G16MpUvNp24Vp85VUnoouPY4uQwfoxegtOyuvnnZNeDE8ofIaJJCucHTsl/k6Us7KULvhNK5LIOaDVCqkodOvAlNS2MSZ+VKXkrbLM6mmfcsN4XbkI58na0JH9gQoPVbR2aO2ioPvJhFZM+VT0sCeYnDbZGZAIU/9KdXJ10wGOhqLyfzhkTqjImW17GySJWe4WcgHYG/jwBUV9FLP1cdupdsAGsw/ZiISL+jE0TNyTByuAvXVQLEue/IHjQz5Qtf0cOCSXKj51EF5msEzy6GDNzMeigWp7VyugBRZz0iYPKVlZriBqoT6JjAiTFyC0SnYq8yNQMM3JFY/RPE+llx6qVSZThpXx/0BJ6GB7MEF9l2GvV4wFhWE2fk42QzTiJDZztU+rsgSndJHIVdMaUApniaDMHoN1eXBaERlwhScfRArp4SvmRRQX6eUSZ9nxFlkKlhQbnVuoLGg3Gho4KGRqfRrDitzqYypr5ORAOlw0GfKRBrM/PWbGPkwt21Phx0e+O7/CoDZ96dB2/VSGh0pJBNPdKJctZiNUlnF6NWdz0oKQHnbFe3IMz26g+Eg00/qxPu2o1z5ml1WB2OXchvtuzGVrcWB6z8BAAD//1Sq+nwCf6hOAAAAAElFTkSuQmCC","media_type":"image/png","type":"base64"},"type":"image"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","type":"text"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"model":"claude-sonnet-4-20250514","id":"msg_013ZUuTN2uLQycJnEdfnweVp","type":"message","role":"assistant","content":[{"type":"text","text":"This image shows a simple, cute green cartoon character or mascot on a colorful gradient background. The character appears to be a rounded, blob-like figure with a friendly appearance, positioned against a background that transitions from purple/blue in the upper left to pink/magenta in the lower right corner. The overall style is minimalist and cheerful."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":27,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":75,"service_tier":"standard"}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 4.253591667s
diff --git a/internal/fantasy/providertests/testdata/TestImageUploadAgent/gemini-2.5-pro.yaml b/internal/fantasy/providertests/testdata/TestImageUploadAgent/gemini-2.5-pro.yaml
new file mode 100644
index 000000000..cf769ef3c
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestImageUploadAgent/gemini-2.5-pro.yaml
@@ -0,0 +1,66 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 4094
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Describe the image briefly in English."},{"inlineData":{"data":"iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAK+0lEQVR4nJSZa48cR9XH/1V9m/us1+td39b7rO04myixkzh5EsdPnhgibsZCCZAoEIGExCskxFfgKyA+AbwAJCQEiPAiMpeAkgDBsdeJQyI77CWxs2vvfWem73VQVXX39Ez3rk2rNJrtnq761f+cOudUrfm95wmDFwOGb+1wJb9kO/+i0NE9dm7u3tVuvbB7GIANd3qPE+a7P96FqeQOG7jP8l/YrqIWOr4LVul7bGjsoSFTvmxK9N/A6R+XGHF3pgEJs7GLg5Gkp9xQ+bfk051NwfJYuzujfMpKEEs+825EBWjKzWeH8QgwM5rdnHHIu4dQlFk1tOwt644KNIOzl2/tMKp576tpQDCWc04G4ukXRcNE8qUPx0ooaWcb3c23cvpTTqREHoUCI9cIiEGx/IQYIGMcjCQu5eCSqRbISrD6P2MFvlQk0kBcdWACdtoEEKgWApH6U8gfWoDN5c+DGIGA0MSZEQtkO4fTHZj6OmkmC3CAOtg4pmbWVlfq2/MO2wQ8UAAWgQtJW+FoVLB/fzy/YLgB3EiSkSJjVGLNciOyoZWfw6K84WwwB9QAO4hnX5h98tAiC+2fXDyzdLnF1mEwaThbwGGoW3jgWHz6nPfrn9bXtmRnvQikNCt17rJwOsjEMtfmOZG04RygBuzFiWfn7j+0wBFWre7L5962j0bUAqvCcmSr13BwL578vHtwJnj4oWikiZqNiqF6ZkPZILmMJ2Z+OMQ08D233OSnFknbzgaqQBv1B3vnzl5qsaCK2ARVLb/SwvVb4whgEUYqeOKR8P+/3BufjhjH4ZlwpEHdTb65xUMhfU87WX50NqxW0Z+KTJZszAEq0qWwD4+fudbmvgNhaA+HeHzyxqGZTWojrkpFzQpxK+2Vk2HBtHNzLmQIAnh5jspeyDzJzInkgJSbYxRTp2+eGLtVQ2RD8CQYCM7CC6dn2QSiOtYJb161X/1Fc3neEgJv/ar52m+rN+aNIFZSFVVgQ0ZkuzJZYHrRaZ0awB407++eP/OPPdyvQCis/tV0PFGx5+6MUog4hhciWjeaNfH6nyprXXgBfIF45/Ri7sjEckwqJpGdc/M22se6z//f3/abXUu5VKH6is8df295q/XhlXF/A5su3l0y1v9cXQngEwKGKEtWrADHSgNExqQXnaNcu6poakAT1Yng1IOLZ49+0DBcDsH6KSYfHAVnwYuPvvXHxsN/n532VljUxca6QcoZojBZ1ETlKZLJornUfJpJ22sv2AQmjmz+z+HVo/tvT4/ctnnAEgcvtURec2PdHbm0OH3to4Mbt6q0Cr4OdBC7oFDmKBYXEmgJlg7lHKSjZR18Sjx94foTRxfbdheIlTaD2a6soKdhb+BE5lJn9PJHU/98Y5LmOW2DfJmgKEZxgmZpNKMUzrbxzKm1ysyiB0/7NRI3olKdNja6IyN1JOmOEVEURpZtyrcYHWjeOfDIWrvae+3nD5ieZOIqp8c07GHlUV5bugK8UMUX77SX4tos7BuwbsPoyURXnjGWPl0/eeT7uW7otVff+e43ftRXUEpD674DBoOjamFynxitwjKGNwE8r3vfAASHcK6KZxxUV6ynZo9vcmuOW/OwlmBugLtlcEEQeV6Yv+P2/F7X152SKiluBY0rVyd5IOvP8Ra++rL79JNh25EJNDO7CqdlWzkbeMzB+aaS2MOJyxPHPjnkwlzm5hKMVRhb4D3wQD3X5a/1/rGa0RyfaOe7arVr7ZG6cXOcr7VjsA7Mi7MPBbcsFshS8fBkNHYoOn4yaDYFG/RNk4atJ9ffCQsv7lFKCsQhaBtn3zh++8LWdn19jQsuyJCVhJwVQZgg0604bz66/znv6sKPZT9dWXJRHZ/9wsnPfO6k8/v7o71b22fef+/O4bnLB1hHVmNhiKvXTBbXF/9tLq8hHnR5FeVzXm8CR0x8Zx9qyt6xqmQEA4v5aNC6Pr0s0ysji2RwNdJEwKwoum8+Hl9jKplZb6P2M4QnQXXGGAumPvUO39mC87u//G8wb7FtwJezjQIsL/Gtniy/qLQM1BHQIOzj+NZeNA15U+gaN4aIEHsYnWsePX5obnI+UBasQzhqJRtqdcfNXhYSgrMInlLUurJ3ogjG1Y+nOgs19KRUIpLmDwRCFR2IhrckPHN3DrQZXhnDuK2YdCghCSdixBEiF/f9axIwhQyBLJILg2FgnSQxTTaD6TvpU+P961PogAW5Ml8klWBxYXP9ElcFwdf3YLqSMGVjxKSaQBTBuVNtdJp6u8CU9fKHDIqDiaQhNyJzw8raUgsqfso55eTJm4/l4xZTGe9LLZyqp0w6s2ggtbBDQiiknza2GlxiJTqnW3+WzCH5lENrPqUo2/DqcFX8FHKZGEMBs3BwIrevFeBsDc+25CCC9aO4HiZKsQKS1Yjh24ZgmbOnk6SMTKHokEhceR4AL7QplLAGwVKxNObwmOy/9OIV4KSDC6OymwHbqfwXqwokVPurQC4gkOA8XYM8Z74YLJSewwP5qRtPLcbi2ID6ZjLULJyaifZUUTdUFB0SSmMds/DSmHycZTuRNikVS4ACBp9B5bGkeFZqMSWS3HcF4D4MT2Yn2VxwTzbJFyPp1yAZd6bHcP6l3mMPRa2q3KixsmMc85v75CYkO4oRrA8kmZjkyJg8IDREisWUIzIBHoL5qmkOApmyaqSKbNJJBBKs+ybjr3yt2xqLn3ulU23VLl60ZdAqGNFsq8gV56XKbKek8jMmhp68SVbCxGLpwdJ2XfBNmOswelyWTwBZEFWIlhAtiBbgx4YOV3MLxh9+2Tj/7a0rF2tvv2UHUa4SzIUTWdiINEFqqaKcVFInrrCYDIQ9uR65NlwsEzZ3YazD/NjdM7cysbrVCsio1Hpjo6sTIytdHmzyuCnEOGitU4ULEaAT4NoNXv9N7d137NVttYkti1umyMVA7eYRVzrlmQBXYwn4rhPACFT1tglzYXP8o8UjK7fbQYhIqCnx5pwxYTbCwwdvT00s+bWtrqCPP9gvK9IAPV9u81//qx1FMufEIt3sD54dsugHpEUSLBWJS6CAw+PwDLiqdSx0HGxX0Z30nXPvmTzeWB399JMDmyt1P5Q5JCREJF8XuhmyviUT1bq//yYasw42tG8m0YzyIZ6G16MpUvNp24Vp85VUnoouPY4uQwfoxegtOyuvnnZNeDE8ofIaJJCucHTsl/k6Us7KULvhNK5LIOaDVCqkodOvAlNS2MSZ+VKXkrbLM6mmfcsN4XbkI58na0JH9gQoPVbR2aO2ioPvJhFZM+VT0sCeYnDbZGZAIU/9KdXJ10wGOhqLyfzhkTqjImW17GySJWe4WcgHYG/jwBUV9FLP1cdupdsAGsw/ZiISL+jE0TNyTByuAvXVQLEue/IHjQz5Qtf0cOCSXKj51EF5msEzy6GDNzMeigWp7VyugBRZz0iYPKVlZriBqoT6JjAiTFyC0SnYq8yNQMM3JFY/RPE+llx6qVSZThpXx/0BJ6GB7MEF9l2GvV4wFhWE2fk42QzTiJDZztU+rsgSndJHIVdMaUApniaDMHoN1eXBaERlwhScfRArp4SvmRRQX6eUSZ9nxFlkKlhQbnVuoLGg3Gho4KGRqfRrDitzqYypr5ORAOlw0GfKRBrM/PWbGPkwt21Phx0e+O7/CoDZ96dB2/VSGh0pJBNPdKJctZiNUlnF6NWdz0oKQHnbFe3IMz26g+Eg00/qxPu2o1z5ml1WB2OXchvtuzGVrcWB6z8BAAD//1Sq+nwCf6hOAAAAAElFTkSuQmCC","mimeType":"image/png"}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.29.0 gl-go/go1.25.0
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "Of course! Here are a few ways to describe the image, from simple to more detailed:\n\n**Very Brief:**\nIt's an illustration of a cute, glowing cartoon star with a blushing face.\n\n**A Bit More Detailed:**\nThis is a kawaii-style digital art piece featuring a softly glowing, pale yellow star. The star has a cute face with simple black eyes and pink, blushing cheeks. It's set against a purple and blue gradient background, with a colorful shadow trail and a few sparkles to its right."
+ }
+ ],
+ "role": "model"
+ },
+ "finishReason": "STOP",
+ "index": 0
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 272,
+ "candidatesTokenCount": 109,
+ "totalTokenCount": 1550,
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 14
+ },
+ {
+ "modality": "IMAGE",
+ "tokenCount": 258
+ }
+ ],
+ "thoughtsTokenCount": 1169
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "responseId": "tiz2aKSJE7eDvdIP8oPkyQQ"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 15.032053917s
diff --git a/internal/fantasy/providertests/testdata/TestImageUploadAgent/openai-gpt-5.yaml b/internal/fantasy/providertests/testdata/TestImageUploadAgent/openai-gpt-5.yaml
new file mode 100644
index 000000000..56cc2ec4a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestImageUploadAgent/openai-gpt-5.yaml
@@ -0,0 +1,68 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 4099
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":[{"text":"Describe the image briefly in English.","type":"text"},{"image_url":{"url":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAK+0lEQVR4nJSZa48cR9XH/1V9m/us1+td39b7rO04myixkzh5EsdPnhgibsZCCZAoEIGExCskxFfgKyA+AbwAJCQEiPAiMpeAkgDBsdeJQyI77CWxs2vvfWem73VQVXX39Ez3rk2rNJrtnq761f+cOudUrfm95wmDFwOGb+1wJb9kO/+i0NE9dm7u3tVuvbB7GIANd3qPE+a7P96FqeQOG7jP8l/YrqIWOr4LVul7bGjsoSFTvmxK9N/A6R+XGHF3pgEJs7GLg5Gkp9xQ+bfk051NwfJYuzujfMpKEEs+825EBWjKzWeH8QgwM5rdnHHIu4dQlFk1tOwt644KNIOzl2/tMKp576tpQDCWc04G4ukXRcNE8qUPx0ooaWcb3c23cvpTTqREHoUCI9cIiEGx/IQYIGMcjCQu5eCSqRbISrD6P2MFvlQk0kBcdWACdtoEEKgWApH6U8gfWoDN5c+DGIGA0MSZEQtkO4fTHZj6OmkmC3CAOtg4pmbWVlfq2/MO2wQ8UAAWgQtJW+FoVLB/fzy/YLgB3EiSkSJjVGLNciOyoZWfw6K84WwwB9QAO4hnX5h98tAiC+2fXDyzdLnF1mEwaThbwGGoW3jgWHz6nPfrn9bXtmRnvQikNCt17rJwOsjEMtfmOZG04RygBuzFiWfn7j+0wBFWre7L5962j0bUAqvCcmSr13BwL578vHtwJnj4oWikiZqNiqF6ZkPZILmMJ2Z+OMQ08D233OSnFknbzgaqQBv1B3vnzl5qsaCK2ARVLb/SwvVb4whgEUYqeOKR8P+/3BufjhjH4ZlwpEHdTb65xUMhfU87WX50NqxW0Z+KTJZszAEq0qWwD4+fudbmvgNhaA+HeHzyxqGZTWojrkpFzQpxK+2Vk2HBtHNzLmQIAnh5jspeyDzJzInkgJSbYxRTp2+eGLtVQ2RD8CQYCM7CC6dn2QSiOtYJb161X/1Fc3neEgJv/ar52m+rN+aNIFZSFVVgQ0ZkuzJZYHrRaZ0awB407++eP/OPPdyvQCis/tV0PFGx5+6MUog4hhciWjeaNfH6nyprXXgBfIF45/Ri7sjEckwqJpGdc/M22se6z//f3/abXUu5VKH6is8df295q/XhlXF/A5su3l0y1v9cXQngEwKGKEtWrADHSgNExqQXnaNcu6poakAT1Yng1IOLZ49+0DBcDsH6KSYfHAVnwYuPvvXHxsN/n532VljUxca6QcoZojBZ1ETlKZLJornUfJpJ22sv2AQmjmz+z+HVo/tvT4/ctnnAEgcvtURec2PdHbm0OH3to4Mbt6q0Cr4OdBC7oFDmKBYXEmgJlg7lHKSjZR18Sjx94foTRxfbdheIlTaD2a6soKdhb+BE5lJn9PJHU/98Y5LmOW2DfJmgKEZxgmZpNKMUzrbxzKm1ysyiB0/7NRI3olKdNja6IyN1JOmOEVEURpZtyrcYHWjeOfDIWrvae+3nD5ieZOIqp8c07GHlUV5bugK8UMUX77SX4tos7BuwbsPoyURXnjGWPl0/eeT7uW7otVff+e43ftRXUEpD674DBoOjamFynxitwjKGNwE8r3vfAASHcK6KZxxUV6ynZo9vcmuOW/OwlmBugLtlcEEQeV6Yv+P2/F7X152SKiluBY0rVyd5IOvP8Ra++rL79JNh25EJNDO7CqdlWzkbeMzB+aaS2MOJyxPHPjnkwlzm5hKMVRhb4D3wQD3X5a/1/rGa0RyfaOe7arVr7ZG6cXOcr7VjsA7Mi7MPBbcsFshS8fBkNHYoOn4yaDYFG/RNk4atJ9ffCQsv7lFKCsQhaBtn3zh++8LWdn19jQsuyJCVhJwVQZgg0604bz66/znv6sKPZT9dWXJRHZ/9wsnPfO6k8/v7o71b22fef+/O4bnLB1hHVmNhiKvXTBbXF/9tLq8hHnR5FeVzXm8CR0x8Zx9qyt6xqmQEA4v5aNC6Pr0s0ysji2RwNdJEwKwoum8+Hl9jKplZb6P2M4QnQXXGGAumPvUO39mC87u//G8wb7FtwJezjQIsL/Gtniy/qLQM1BHQIOzj+NZeNA15U+gaN4aIEHsYnWsePX5obnI+UBasQzhqJRtqdcfNXhYSgrMInlLUurJ3ogjG1Y+nOgs19KRUIpLmDwRCFR2IhrckPHN3DrQZXhnDuK2YdCghCSdixBEiF/f9axIwhQyBLJILg2FgnSQxTTaD6TvpU+P961PogAW5Ml8klWBxYXP9ElcFwdf3YLqSMGVjxKSaQBTBuVNtdJp6u8CU9fKHDIqDiaQhNyJzw8raUgsqfso55eTJm4/l4xZTGe9LLZyqp0w6s2ggtbBDQiiknza2GlxiJTqnW3+WzCH5lENrPqUo2/DqcFX8FHKZGEMBs3BwIrevFeBsDc+25CCC9aO4HiZKsQKS1Yjh24ZgmbOnk6SMTKHokEhceR4AL7QplLAGwVKxNObwmOy/9OIV4KSDC6OymwHbqfwXqwokVPurQC4gkOA8XYM8Z74YLJSewwP5qRtPLcbi2ID6ZjLULJyaifZUUTdUFB0SSmMds/DSmHycZTuRNikVS4ACBp9B5bGkeFZqMSWS3HcF4D4MT2Yn2VxwTzbJFyPp1yAZd6bHcP6l3mMPRa2q3KixsmMc85v75CYkO4oRrA8kmZjkyJg8IDREisWUIzIBHoL5qmkOApmyaqSKbNJJBBKs+ybjr3yt2xqLn3ulU23VLl60ZdAqGNFsq8gV56XKbKek8jMmhp68SVbCxGLpwdJ2XfBNmOswelyWTwBZEFWIlhAtiBbgx4YOV3MLxh9+2Tj/7a0rF2tvv2UHUa4SzIUTWdiINEFqqaKcVFInrrCYDIQ9uR65NlwsEzZ3YazD/NjdM7cysbrVCsio1Hpjo6sTIytdHmzyuCnEOGitU4ULEaAT4NoNXv9N7d137NVttYkti1umyMVA7eYRVzrlmQBXYwn4rhPACFT1tglzYXP8o8UjK7fbQYhIqCnx5pwxYTbCwwdvT00s+bWtrqCPP9gvK9IAPV9u81//qx1FMufEIt3sD54dsugHpEUSLBWJS6CAw+PwDLiqdSx0HGxX0Z30nXPvmTzeWB399JMDmyt1P5Q5JCREJF8XuhmyviUT1bq//yYasw42tG8m0YzyIZ6G16MpUvNp24Vp85VUnoouPY4uQwfoxegtOyuvnnZNeDE8ofIaJJCucHTsl/k6Us7KULvhNK5LIOaDVCqkodOvAlNS2MSZ+VKXkrbLM6mmfcsN4XbkI58na0JH9gQoPVbR2aO2ioPvJhFZM+VT0sCeYnDbZGZAIU/9KdXJ10wGOhqLyfzhkTqjImW17GySJWe4WcgHYG/jwBUV9FLP1cdupdsAGsw/ZiISL+jE0TNyTByuAvXVQLEue/IHjQz5Qtf0cOCSXKj51EF5msEzy6GDNzMeigWp7VyugBRZz0iYPKVlZriBqoT6JjAiTFyC0SnYq8yNQMM3JFY/RPE+llx6qVSZThpXx/0BJ6GB7MEF9l2GvV4wFhWE2fk42QzTiJDZztU+rsgSndJHIVdMaUApniaDMHoN1eXBaERlwhScfRArp4SvmRRQX6eUSZ9nxFlkKlhQbnVuoLGg3Gho4KGRqfRrDitzqYypr5ORAOlw0GfKRBrM/PWbGPkwt21Phx0e+O7/CoDZ96dB2/VSGh0pJBNPdKJctZiNUlnF6NWdz0oKQHnbFe3IMz26g+Eg00/qxPu2o1z5ml1WB2OXchvtuzGVrcWB6z8BAAD//1Sq+nwCf6hOAAAAAElFTkSuQmCC"},"type":"image_url"}],"role":"user"}],"model":"gpt-5","max_completion_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CSjOzVpF3I8bIXI82utKxQ0hurdzG",
+ "object": "chat.completion",
+ "created": 1760963745,
+ "model": "gpt-5-2025-08-07",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "A cute pastel star with a tiny face streaks across a purple background, leaving a pink-to-teal trail and sparkles.",
+ "refusal": null,
+ "annotations": []
+ },
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 232,
+ "completion_tokens": 99,
+ "total_tokens": 331,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 64,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": null
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 6.903364166s
diff --git a/internal/fantasy/providertests/testdata/TestImageUploadAgentStreaming/anthropic-claude-sonnet-4-stream.yaml b/internal/fantasy/providertests/testdata/TestImageUploadAgentStreaming/anthropic-claude-sonnet-4-stream.yaml
new file mode 100644
index 000000000..b149459a9
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestImageUploadAgentStreaming/anthropic-claude-sonnet-4-stream.yaml
@@ -0,0 +1,143 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 4140
+ host: ""
+ body: '{"max_tokens":4000,"messages":[{"content":[{"text":"Describe the image briefly in English.","type":"text"},{"source":{"data":"iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAK+0lEQVR4nJSZa48cR9XH/1V9m/us1+td39b7rO04myixkzh5EsdPnhgibsZCCZAoEIGExCskxFfgKyA+AbwAJCQEiPAiMpeAkgDBsdeJQyI77CWxs2vvfWem73VQVXX39Ez3rk2rNJrtnq761f+cOudUrfm95wmDFwOGb+1wJb9kO/+i0NE9dm7u3tVuvbB7GIANd3qPE+a7P96FqeQOG7jP8l/YrqIWOr4LVul7bGjsoSFTvmxK9N/A6R+XGHF3pgEJs7GLg5Gkp9xQ+bfk051NwfJYuzujfMpKEEs+825EBWjKzWeH8QgwM5rdnHHIu4dQlFk1tOwt644KNIOzl2/tMKp576tpQDCWc04G4ukXRcNE8qUPx0ooaWcb3c23cvpTTqREHoUCI9cIiEGx/IQYIGMcjCQu5eCSqRbISrD6P2MFvlQk0kBcdWACdtoEEKgWApH6U8gfWoDN5c+DGIGA0MSZEQtkO4fTHZj6OmkmC3CAOtg4pmbWVlfq2/MO2wQ8UAAWgQtJW+FoVLB/fzy/YLgB3EiSkSJjVGLNciOyoZWfw6K84WwwB9QAO4hnX5h98tAiC+2fXDyzdLnF1mEwaThbwGGoW3jgWHz6nPfrn9bXtmRnvQikNCt17rJwOsjEMtfmOZG04RygBuzFiWfn7j+0wBFWre7L5962j0bUAqvCcmSr13BwL578vHtwJnj4oWikiZqNiqF6ZkPZILmMJ2Z+OMQ08D233OSnFknbzgaqQBv1B3vnzl5qsaCK2ARVLb/SwvVb4whgEUYqeOKR8P+/3BufjhjH4ZlwpEHdTb65xUMhfU87WX50NqxW0Z+KTJZszAEq0qWwD4+fudbmvgNhaA+HeHzyxqGZTWojrkpFzQpxK+2Vk2HBtHNzLmQIAnh5jspeyDzJzInkgJSbYxRTp2+eGLtVQ2RD8CQYCM7CC6dn2QSiOtYJb161X/1Fc3neEgJv/ar52m+rN+aNIFZSFVVgQ0ZkuzJZYHrRaZ0awB407++eP/OPPdyvQCis/tV0PFGx5+6MUog4hhciWjeaNfH6nyprXXgBfIF45/Ri7sjEckwqJpGdc/M22se6z//f3/abXUu5VKH6is8df295q/XhlXF/A5su3l0y1v9cXQngEwKGKEtWrADHSgNExqQXnaNcu6poakAT1Yng1IOLZ49+0DBcDsH6KSYfHAVnwYuPvvXHxsN/n532VljUxca6QcoZojBZ1ETlKZLJornUfJpJ22sv2AQmjmz+z+HVo/tvT4/ctnnAEgcvtURec2PdHbm0OH3to4Mbt6q0Cr4OdBC7oFDmKBYXEmgJlg7lHKSjZR18Sjx94foTRxfbdheIlTaD2a6soKdhb+BE5lJn9PJHU/98Y5LmOW2DfJmgKEZxgmZpNKMUzrbxzKm1ysyiB0/7NRI3olKdNja6IyN1JOmOEVEURpZtyrcYHWjeOfDIWrvae+3nD5ieZOIqp8c07GHlUV5bugK8UMUX77SX4tos7BuwbsPoyURXnjGWPl0/eeT7uW7otVff+e43ftRXUEpD674DBoOjamFynxitwjKGNwE8r3vfAASHcK6KZxxUV6ynZo9vcmuOW/OwlmBugLtlcEEQeV6Yv+P2/F7X152SKiluBY0rVyd5IOvP8Ra++rL79JNh25EJNDO7CqdlWzkbeMzB+aaS2MOJyxPHPjnkwlzm5hKMVRhb4D3wQD3X5a/1/rGa0RyfaOe7arVr7ZG6cXOcr7VjsA7Mi7MPBbcsFshS8fBkNHYoOn4yaDYFG/RNk4atJ9ffCQsv7lFKCsQhaBtn3zh++8LWdn19jQsuyJCVhJwVQZgg0604bz66/znv6sKPZT9dWXJRHZ/9wsnPfO6k8/v7o71b22fef+/O4bnLB1hHVmNhiKvXTBbXF/9tLq8hHnR5FeVzXm8CR0x8Zx9qyt6xqmQEA4v5aNC6Pr0s0ysji2RwNdJEwKwoum8+Hl9jKplZb6P2M4QnQXXGGAumPvUO39mC87u//G8wb7FtwJezjQIsL/Gtniy/qLQM1BHQIOzj+NZeNA15U+gaN4aIEHsYnWsePX5obnI+UBasQzhqJRtqdcfNXhYSgrMInlLUurJ3ogjG1Y+nOgs19KRUIpLmDwRCFR2IhrckPHN3DrQZXhnDuK2YdCghCSdixBEiF/f9axIwhQyBLJILg2FgnSQxTTaD6TvpU+P961PogAW5Ml8klWBxYXP9ElcFwdf3YLqSMGVjxKSaQBTBuVNtdJp6u8CU9fKHDIqDiaQhNyJzw8raUgsqfso55eTJm4/l4xZTGe9LLZyqp0w6s2ggtbBDQiiknza2GlxiJTqnW3+WzCH5lENrPqUo2/DqcFX8FHKZGEMBs3BwIrevFeBsDc+25CCC9aO4HiZKsQKS1Yjh24ZgmbOnk6SMTKHokEhceR4AL7QplLAGwVKxNObwmOy/9OIV4KSDC6OymwHbqfwXqwokVPurQC4gkOA8XYM8Z74YLJSewwP5qRtPLcbi2ID6ZjLULJyaifZUUTdUFB0SSmMds/DSmHycZTuRNikVS4ACBp9B5bGkeFZqMSWS3HcF4D4MT2Yn2VxwTzbJFyPp1yAZd6bHcP6l3mMPRa2q3KixsmMc85v75CYkO4oRrA8kmZjkyJg8IDREisWUIzIBHoL5qmkOApmyaqSKbNJJBBKs+ybjr3yt2xqLn3ulU23VLl60ZdAqGNFsq8gV56XKbKek8jMmhp68SVbCxGLpwdJ2XfBNmOswelyWTwBZEFWIlhAtiBbgx4YOV3MLxh9+2Tj/7a0rF2tvv2UHUa4SzIUTWdiINEFqqaKcVFInrrCYDIQ9uR65NlwsEzZ3YazD/NjdM7cysbrVCsio1Hpjo6sTIytdHmzyuCnEOGitU4ULEaAT4NoNXv9N7d137NVttYkti1umyMVA7eYRVzrlmQBXYwn4rhPACFT1tglzYXP8o8UjK7fbQYhIqCnx5pwxYTbCwwdvT00s+bWtrqCPP9gvK9IAPV9u81//qx1FMufEIt3sD54dsugHpEUSLBWJS6CAw+PwDLiqdSx0HGxX0Z30nXPvmTzeWB399JMDmyt1P5Q5JCREJF8XuhmyviUT1bq//yYasw42tG8m0YzyIZ6G16MpUvNp24Vp85VUnoouPY4uQwfoxegtOyuvnnZNeDE8ofIaJJCucHTsl/k6Us7KULvhNK5LIOaDVCqkodOvAlNS2MSZ+VKXkrbLM6mmfcsN4XbkI58na0JH9gQoPVbR2aO2ioPvJhFZM+VT0sCeYnDbZGZAIU/9KdXJ10wGOhqLyfzhkTqjImW17GySJWe4WcgHYG/jwBUV9FLP1cdupdsAGsw/ZiISL+jE0TNyTByuAvXVQLEue/IHjQz5Qtf0cOCSXKj51EF5msEzy6GDNzMeigWp7VyugBRZz0iYPKVlZriBqoT6JjAiTFyC0SnYq8yNQMM3JFY/RPE+llx6qVSZThpXx/0BJ6GB7MEF9l2GvV4wFhWE2fk42QzTiJDZztU+rsgSndJHIVdMaUApniaDMHoN1eXBaERlwhScfRArp4SvmRRQX6eUSZ9nxFlkKlhQbnVuoLGg3Gho4KGRqfRrDitzqYypr5ORAOlw0GfKRBrM/PWbGPkwt21Phx0e+O7/CoDZ96dB2/VSGh0pJBNPdKJctZiNUlnF6NWdz0oKQHnbFe3IMz26g+Eg00/qxPu2o1z5ml1WB2OXchvtuzGVrcWB6z8BAAD//1Sq+nwCf6hOAAAAAElFTkSuQmCC","media_type":"image/png","type":"base64"},"type":"image"}],"role":"user"}],"model":"claude-sonnet-4-20250514","system":[{"text":"You are a helpful assistant","type":"text"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - Anthropic/Go 1.13.0
+ url: https://api.anthropic.com/v1/messages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: message_start
+ data: {"type":"message_start","message":{"model":"claude-sonnet-4-20250514","id":"msg_012xohG7vsYehZ9GLHx725XU","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":27,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}} }
+
+ event: content_block_start
+ data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"This"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" image"} }
+
+ event: ping
+ data: {"type": "ping"}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" shows"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" a simple"}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":","} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" minimalist illustration"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" of a cute"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" green"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" frog or"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" f"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"rog-like character"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" sitting"}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" against"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" a soft"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" gradient background that"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" transitions"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" from purple/"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"blue on"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" the left to pink on"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" the right. The frog appears"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" to be rendere"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"d in a kawaii or"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" adorable cartoon"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" style with a"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" rounded, simple"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" design."} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" The"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" overall"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" aesthetic is clean and ple"}}
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"asing with"} }
+
+ event: content_block_delta
+ data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" pastel colors."} }
+
+ event: content_block_stop
+ data: {"type":"content_block_stop","index":0 }
+
+ event: message_delta
+ data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":27,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":81} }
+
+ event: message_stop
+ data: {"type":"message_stop" }
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.594873792s
diff --git a/internal/fantasy/providertests/testdata/TestImageUploadAgentStreaming/gemini-2.5-pro-stream.yaml b/internal/fantasy/providertests/testdata/TestImageUploadAgentStreaming/gemini-2.5-pro-stream.yaml
new file mode 100644
index 000000000..6cf8320b9
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestImageUploadAgentStreaming/gemini-2.5-pro-stream.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 4094
+ host: generativelanguage.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Describe the image briefly in English."},{"inlineData":{"data":"iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAK+0lEQVR4nJSZa48cR9XH/1V9m/us1+td39b7rO04myixkzh5EsdPnhgibsZCCZAoEIGExCskxFfgKyA+AbwAJCQEiPAiMpeAkgDBsdeJQyI77CWxs2vvfWem73VQVXX39Ez3rk2rNJrtnq761f+cOudUrfm95wmDFwOGb+1wJb9kO/+i0NE9dm7u3tVuvbB7GIANd3qPE+a7P96FqeQOG7jP8l/YrqIWOr4LVul7bGjsoSFTvmxK9N/A6R+XGHF3pgEJs7GLg5Gkp9xQ+bfk051NwfJYuzujfMpKEEs+825EBWjKzWeH8QgwM5rdnHHIu4dQlFk1tOwt644KNIOzl2/tMKp576tpQDCWc04G4ukXRcNE8qUPx0ooaWcb3c23cvpTTqREHoUCI9cIiEGx/IQYIGMcjCQu5eCSqRbISrD6P2MFvlQk0kBcdWACdtoEEKgWApH6U8gfWoDN5c+DGIGA0MSZEQtkO4fTHZj6OmkmC3CAOtg4pmbWVlfq2/MO2wQ8UAAWgQtJW+FoVLB/fzy/YLgB3EiSkSJjVGLNciOyoZWfw6K84WwwB9QAO4hnX5h98tAiC+2fXDyzdLnF1mEwaThbwGGoW3jgWHz6nPfrn9bXtmRnvQikNCt17rJwOsjEMtfmOZG04RygBuzFiWfn7j+0wBFWre7L5962j0bUAqvCcmSr13BwL578vHtwJnj4oWikiZqNiqF6ZkPZILmMJ2Z+OMQ08D233OSnFknbzgaqQBv1B3vnzl5qsaCK2ARVLb/SwvVb4whgEUYqeOKR8P+/3BufjhjH4ZlwpEHdTb65xUMhfU87WX50NqxW0Z+KTJZszAEq0qWwD4+fudbmvgNhaA+HeHzyxqGZTWojrkpFzQpxK+2Vk2HBtHNzLmQIAnh5jspeyDzJzInkgJSbYxRTp2+eGLtVQ2RD8CQYCM7CC6dn2QSiOtYJb161X/1Fc3neEgJv/ar52m+rN+aNIFZSFVVgQ0ZkuzJZYHrRaZ0awB407++eP/OPPdyvQCis/tV0PFGx5+6MUog4hhciWjeaNfH6nyprXXgBfIF45/Ri7sjEckwqJpGdc/M22se6z//f3/abXUu5VKH6is8df295q/XhlXF/A5su3l0y1v9cXQngEwKGKEtWrADHSgNExqQXnaNcu6poakAT1Yng1IOLZ49+0DBcDsH6KSYfHAVnwYuPvvXHxsN/n532VljUxca6QcoZojBZ1ETlKZLJornUfJpJ22sv2AQmjmz+z+HVo/tvT4/ctnnAEgcvtURec2PdHbm0OH3to4Mbt6q0Cr4OdBC7oFDmKBYXEmgJlg7lHKSjZR18Sjx94foTRxfbdheIlTaD2a6soKdhb+BE5lJn9PJHU/98Y5LmOW2DfJmgKEZxgmZpNKMUzrbxzKm1ysyiB0/7NRI3olKdNja6IyN1JOmOEVEURpZtyrcYHWjeOfDIWrvae+3nD5ieZOIqp8c07GHlUV5bugK8UMUX77SX4tos7BuwbsPoyURXnjGWPl0/eeT7uW7otVff+e43ftRXUEpD674DBoOjamFynxitwjKGNwE8r3vfAASHcK6KZxxUV6ynZo9vcmuOW/OwlmBugLtlcEEQeV6Yv+P2/F7X152SKiluBY0rVyd5IOvP8Ra++rL79JNh25EJNDO7CqdlWzkbeMzB+aaS2MOJyxPHPjnkwlzm5hKMVRhb4D3wQD3X5a/1/rGa0RyfaOe7arVr7ZG6cXOcr7VjsA7Mi7MPBbcsFshS8fBkNHYoOn4yaDYFG/RNk4atJ9ffCQsv7lFKCsQhaBtn3zh++8LWdn19jQsuyJCVhJwVQZgg0604bz66/znv6sKPZT9dWXJRHZ/9wsnPfO6k8/v7o71b22fef+/O4bnLB1hHVmNhiKvXTBbXF/9tLq8hHnR5FeVzXm8CR0x8Zx9qyt6xqmQEA4v5aNC6Pr0s0ysji2RwNdJEwKwoum8+Hl9jKplZb6P2M4QnQXXGGAumPvUO39mC87u//G8wb7FtwJezjQIsL/Gtniy/qLQM1BHQIOzj+NZeNA15U+gaN4aIEHsYnWsePX5obnI+UBasQzhqJRtqdcfNXhYSgrMInlLUurJ3ogjG1Y+nOgs19KRUIpLmDwRCFR2IhrckPHN3DrQZXhnDuK2YdCghCSdixBEiF/f9axIwhQyBLJILg2FgnSQxTTaD6TvpU+P961PogAW5Ml8klWBxYXP9ElcFwdf3YLqSMGVjxKSaQBTBuVNtdJp6u8CU9fKHDIqDiaQhNyJzw8raUgsqfso55eTJm4/l4xZTGe9LLZyqp0w6s2ggtbBDQiiknza2GlxiJTqnW3+WzCH5lENrPqUo2/DqcFX8FHKZGEMBs3BwIrevFeBsDc+25CCC9aO4HiZKsQKS1Yjh24ZgmbOnk6SMTKHokEhceR4AL7QplLAGwVKxNObwmOy/9OIV4KSDC6OymwHbqfwXqwokVPurQC4gkOA8XYM8Z74YLJSewwP5qRtPLcbi2ID6ZjLULJyaifZUUTdUFB0SSmMds/DSmHycZTuRNikVS4ACBp9B5bGkeFZqMSWS3HcF4D4MT2Yn2VxwTzbJFyPp1yAZd6bHcP6l3mMPRa2q3KixsmMc85v75CYkO4oRrA8kmZjkyJg8IDREisWUIzIBHoL5qmkOApmyaqSKbNJJBBKs+ybjr3yt2xqLn3ulU23VLl60ZdAqGNFsq8gV56XKbKek8jMmhp68SVbCxGLpwdJ2XfBNmOswelyWTwBZEFWIlhAtiBbgx4YOV3MLxh9+2Tj/7a0rF2tvv2UHUa4SzIUTWdiINEFqqaKcVFInrrCYDIQ9uR65NlwsEzZ3YazD/NjdM7cysbrVCsio1Hpjo6sTIytdHmzyuCnEOGitU4ULEaAT4NoNXv9N7d137NVttYkti1umyMVA7eYRVzrlmQBXYwn4rhPACFT1tglzYXP8o8UjK7fbQYhIqCnx5pwxYTbCwwdvT00s+bWtrqCPP9gvK9IAPV9u81//qx1FMufEIt3sD54dsugHpEUSLBWJS6CAw+PwDLiqdSx0HGxX0Z30nXPvmTzeWB399JMDmyt1P5Q5JCREJF8XuhmyviUT1bq//yYasw42tG8m0YzyIZ6G16MpUvNp24Vp85VUnoouPY4uQwfoxegtOyuvnnZNeDE8ofIaJJCucHTsl/k6Us7KULvhNK5LIOaDVCqkodOvAlNS2MSZ+VKXkrbLM6mmfcsN4XbkI58na0JH9gQoPVbR2aO2ioPvJhFZM+VT0sCeYnDbZGZAIU/9KdXJ10wGOhqLyfzhkTqjImW17GySJWe4WcgHYG/jwBUV9FLP1cdupdsAGsw/ZiISL+jE0TNyTByuAvXVQLEue/IHjQz5Qtf0cOCSXKj51EF5msEzy6GDNzMeigWp7VyugBRZz0iYPKVlZriBqoT6JjAiTFyC0SnYq8yNQMM3JFY/RPE+llx6qVSZThpXx/0BJ6GB7MEF9l2GvV4wFhWE2fk42QzTiJDZztU+rsgSndJHIVdMaUApniaDMHoN1eXBaERlwhScfRArp4SvmRRQX6eUSZ9nxFlkKlhQbnVuoLGg3Gho4KGRqfRrDitzqYypr5ORAOlw0GfKRBrM/PWbGPkwt21Phx0e+O7/CoDZ96dB2/VSGh0pJBNPdKJctZiNUlnF6NWdz0oKQHnbFe3IMz26g+Eg00/qxPu2o1z5ml1WB2OXchvtuzGVrcWB6z8BAAD//1Sq+nwCf6hOAAAAAElFTkSuQmCC","mimeType":"image/png"}}],"role":"user"}],"generationConfig":{"maxOutputTokens":4000},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"}}
+ form:
+ alt:
+ - sse
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.29.0 gl-go/go1.25.0
+ url: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:streamGenerateContent?alt=sse
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"Of course! Here are a few ways to describe the image, from brief to more detailed:\\n\\n**Very Brief:**\\n\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 272,\"candidatesTokenCount\": 24,\"totalTokenCount\": 1401,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 14},{\"modality\": \"IMAGE\",\"tokenCount\": 258}],\"thoughtsTokenCount\": 1105},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"wCz2aMDSAZe_vdIPyOrHoA8\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"This is an illustration of a cute, glowing cartoon star with a face, set against a purple background with sparkles and a rainbow trail.\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 272,\"candidatesTokenCount\": 51,\"totalTokenCount\": 1428,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 14},{\"modality\": \"IMAGE\",\"tokenCount\": 258}],\"thoughtsTokenCount\": 1105},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"wCz2aMDSAZe_vdIPyOrHoA8\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"\\n\\n**Slightly More Detailed:**\\nThe image features a soft, pale yellow-green cartoon star with a sweet\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 272,\"candidatesTokenCount\": 74,\"totalTokenCount\": 1451,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 14},{\"modality\": \"IMAGE\",\"tokenCount\": 258}],\"thoughtsTokenCount\": 1105},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"wCz2aMDSAZe_vdIPyOrHoA8\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \", simple face composed of small black eyes, rosy cheeks, and a tiny mouth. The star appears luminous against a purple and blue\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 272,\"candidatesTokenCount\": 100,\"totalTokenCount\": 1477,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 14},{\"modality\": \"IMAGE\",\"tokenCount\": 258}],\"thoughtsTokenCount\": 1105},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"wCz2aMDSAZe_vdIPyOrHoA8\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \" gradient background. It casts a long, colorful, rainbow-like shadow to its left and is accompanied by several white sparkles to its\"}],\"role\": \"model\"},\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 272,\"candidatesTokenCount\": 126,\"totalTokenCount\": 1503,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 14},{\"modality\": \"IMAGE\",\"tokenCount\": 258}],\"thoughtsTokenCount\": 1105},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"wCz2aMDSAZe_vdIPyOrHoA8\"}\r\n\r\ndata: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \" right, giving the artwork a magical and whimsical feel.\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 272,\"candidatesTokenCount\": 137,\"totalTokenCount\": 1514,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 14},{\"modality\": \"IMAGE\",\"tokenCount\": 258}],\"thoughtsTokenCount\": 1105},\"modelVersion\": \"gemini-2.5-pro\",\"responseId\": \"wCz2aMDSAZe_vdIPyOrHoA8\"}\r\n\r\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 13.110220625s
diff --git a/internal/fantasy/providertests/testdata/TestImageUploadAgentStreaming/openai-gpt-5-stream.yaml b/internal/fantasy/providertests/testdata/TestImageUploadAgentStreaming/openai-gpt-5-stream.yaml
new file mode 100644
index 000000000..51d8d5200
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestImageUploadAgentStreaming/openai-gpt-5-stream.yaml
@@ -0,0 +1,86 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 4153
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":[{"text":"Describe the image briefly in English.","type":"text"},{"image_url":{"url":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAK+0lEQVR4nJSZa48cR9XH/1V9m/us1+td39b7rO04myixkzh5EsdPnhgibsZCCZAoEIGExCskxFfgKyA+AbwAJCQEiPAiMpeAkgDBsdeJQyI77CWxs2vvfWem73VQVXX39Ez3rk2rNJrtnq761f+cOudUrfm95wmDFwOGb+1wJb9kO/+i0NE9dm7u3tVuvbB7GIANd3qPE+a7P96FqeQOG7jP8l/YrqIWOr4LVul7bGjsoSFTvmxK9N/A6R+XGHF3pgEJs7GLg5Gkp9xQ+bfk051NwfJYuzujfMpKEEs+825EBWjKzWeH8QgwM5rdnHHIu4dQlFk1tOwt644KNIOzl2/tMKp576tpQDCWc04G4ukXRcNE8qUPx0ooaWcb3c23cvpTTqREHoUCI9cIiEGx/IQYIGMcjCQu5eCSqRbISrD6P2MFvlQk0kBcdWACdtoEEKgWApH6U8gfWoDN5c+DGIGA0MSZEQtkO4fTHZj6OmkmC3CAOtg4pmbWVlfq2/MO2wQ8UAAWgQtJW+FoVLB/fzy/YLgB3EiSkSJjVGLNciOyoZWfw6K84WwwB9QAO4hnX5h98tAiC+2fXDyzdLnF1mEwaThbwGGoW3jgWHz6nPfrn9bXtmRnvQikNCt17rJwOsjEMtfmOZG04RygBuzFiWfn7j+0wBFWre7L5962j0bUAqvCcmSr13BwL578vHtwJnj4oWikiZqNiqF6ZkPZILmMJ2Z+OMQ08D233OSnFknbzgaqQBv1B3vnzl5qsaCK2ARVLb/SwvVb4whgEUYqeOKR8P+/3BufjhjH4ZlwpEHdTb65xUMhfU87WX50NqxW0Z+KTJZszAEq0qWwD4+fudbmvgNhaA+HeHzyxqGZTWojrkpFzQpxK+2Vk2HBtHNzLmQIAnh5jspeyDzJzInkgJSbYxRTp2+eGLtVQ2RD8CQYCM7CC6dn2QSiOtYJb161X/1Fc3neEgJv/ar52m+rN+aNIFZSFVVgQ0ZkuzJZYHrRaZ0awB407++eP/OPPdyvQCis/tV0PFGx5+6MUog4hhciWjeaNfH6nyprXXgBfIF45/Ri7sjEckwqJpGdc/M22se6z//f3/abXUu5VKH6is8df295q/XhlXF/A5su3l0y1v9cXQngEwKGKEtWrADHSgNExqQXnaNcu6poakAT1Yng1IOLZ49+0DBcDsH6KSYfHAVnwYuPvvXHxsN/n532VljUxca6QcoZojBZ1ETlKZLJornUfJpJ22sv2AQmjmz+z+HVo/tvT4/ctnnAEgcvtURec2PdHbm0OH3to4Mbt6q0Cr4OdBC7oFDmKBYXEmgJlg7lHKSjZR18Sjx94foTRxfbdheIlTaD2a6soKdhb+BE5lJn9PJHU/98Y5LmOW2DfJmgKEZxgmZpNKMUzrbxzKm1ysyiB0/7NRI3olKdNja6IyN1JOmOEVEURpZtyrcYHWjeOfDIWrvae+3nD5ieZOIqp8c07GHlUV5bugK8UMUX77SX4tos7BuwbsPoyURXnjGWPl0/eeT7uW7otVff+e43ftRXUEpD674DBoOjamFynxitwjKGNwE8r3vfAASHcK6KZxxUV6ynZo9vcmuOW/OwlmBugLtlcEEQeV6Yv+P2/F7X152SKiluBY0rVyd5IOvP8Ra++rL79JNh25EJNDO7CqdlWzkbeMzB+aaS2MOJyxPHPjnkwlzm5hKMVRhb4D3wQD3X5a/1/rGa0RyfaOe7arVr7ZG6cXOcr7VjsA7Mi7MPBbcsFshS8fBkNHYoOn4yaDYFG/RNk4atJ9ffCQsv7lFKCsQhaBtn3zh++8LWdn19jQsuyJCVhJwVQZgg0604bz66/znv6sKPZT9dWXJRHZ/9wsnPfO6k8/v7o71b22fef+/O4bnLB1hHVmNhiKvXTBbXF/9tLq8hHnR5FeVzXm8CR0x8Zx9qyt6xqmQEA4v5aNC6Pr0s0ysji2RwNdJEwKwoum8+Hl9jKplZb6P2M4QnQXXGGAumPvUO39mC87u//G8wb7FtwJezjQIsL/Gtniy/qLQM1BHQIOzj+NZeNA15U+gaN4aIEHsYnWsePX5obnI+UBasQzhqJRtqdcfNXhYSgrMInlLUurJ3ogjG1Y+nOgs19KRUIpLmDwRCFR2IhrckPHN3DrQZXhnDuK2YdCghCSdixBEiF/f9axIwhQyBLJILg2FgnSQxTTaD6TvpU+P961PogAW5Ml8klWBxYXP9ElcFwdf3YLqSMGVjxKSaQBTBuVNtdJp6u8CU9fKHDIqDiaQhNyJzw8raUgsqfso55eTJm4/l4xZTGe9LLZyqp0w6s2ggtbBDQiiknza2GlxiJTqnW3+WzCH5lENrPqUo2/DqcFX8FHKZGEMBs3BwIrevFeBsDc+25CCC9aO4HiZKsQKS1Yjh24ZgmbOnk6SMTKHokEhceR4AL7QplLAGwVKxNObwmOy/9OIV4KSDC6OymwHbqfwXqwokVPurQC4gkOA8XYM8Z74YLJSewwP5qRtPLcbi2ID6ZjLULJyaifZUUTdUFB0SSmMds/DSmHycZTuRNikVS4ACBp9B5bGkeFZqMSWS3HcF4D4MT2Yn2VxwTzbJFyPp1yAZd6bHcP6l3mMPRa2q3KixsmMc85v75CYkO4oRrA8kmZjkyJg8IDREisWUIzIBHoL5qmkOApmyaqSKbNJJBBKs+ybjr3yt2xqLn3ulU23VLl60ZdAqGNFsq8gV56XKbKek8jMmhp68SVbCxGLpwdJ2XfBNmOswelyWTwBZEFWIlhAtiBbgx4YOV3MLxh9+2Tj/7a0rF2tvv2UHUa4SzIUTWdiINEFqqaKcVFInrrCYDIQ9uR65NlwsEzZ3YazD/NjdM7cysbrVCsio1Hpjo6sTIytdHmzyuCnEOGitU4ULEaAT4NoNXv9N7d137NVttYkti1umyMVA7eYRVzrlmQBXYwn4rhPACFT1tglzYXP8o8UjK7fbQYhIqCnx5pwxYTbCwwdvT00s+bWtrqCPP9gvK9IAPV9u81//qx1FMufEIt3sD54dsugHpEUSLBWJS6CAw+PwDLiqdSx0HGxX0Z30nXPvmTzeWB399JMDmyt1P5Q5JCREJF8XuhmyviUT1bq//yYasw42tG8m0YzyIZ6G16MpUvNp24Vp85VUnoouPY4uQwfoxegtOyuvnnZNeDE8ofIaJJCucHTsl/k6Us7KULvhNK5LIOaDVCqkodOvAlNS2MSZ+VKXkrbLM6mmfcsN4XbkI58na0JH9gQoPVbR2aO2ioPvJhFZM+VT0sCeYnDbZGZAIU/9KdXJ10wGOhqLyfzhkTqjImW17GySJWe4WcgHYG/jwBUV9FLP1cdupdsAGsw/ZiISL+jE0TNyTByuAvXVQLEue/IHjQz5Qtf0cOCSXKj51EF5msEzy6GDNzMeigWp7VyugBRZz0iYPKVlZriBqoT6JjAiTFyC0SnYq8yNQMM3JFY/RPE+llx6qVSZThpXx/0BJ6GB7MEF9l2GvV4wFhWE2fk42QzTiJDZztU+rsgSndJHIVdMaUApniaDMHoN1eXBaERlwhScfRArp4SvmRRQX6eUSZ9nxFlkKlhQbnVuoLGg3Gho4KGRqfRrDitzqYypr5ORAOlw0GfKRBrM/PWbGPkwt21Phx0e+O7/CoDZ96dB2/VSGh0pJBNPdKJctZiNUlnF6NWdz0oKQHnbFe3IMz26g+Eg00/qxPu2o1z5ml1WB2OXchvtuzGVrcWB6z8BAAD//1Sq+nwCf6hOAAAAAElFTkSuQmCC"},"type":"image_url"}],"role":"user"}],"model":"gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"raRip0l73J"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"A"},"finish_reason":null}],"usage":null,"obfuscation":"8CrJkrrq1z4"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" cute"},"finish_reason":null}],"usage":null,"obfuscation":"5c6f05B"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" cartoon"},"finish_reason":null}],"usage":null,"obfuscation":"3eyk"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" star"},"finish_reason":null}],"usage":null,"obfuscation":"pFNjqVq"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" with"},"finish_reason":null}],"usage":null,"obfuscation":"zl76zei"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"finish_reason":null}],"usage":null,"obfuscation":"yLrZnPwm3s"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" face"},"finish_reason":null}],"usage":null,"obfuscation":"9wj1Lkt"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" gl"},"finish_reason":null}],"usage":null,"obfuscation":"gCVYgUgmr"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"ides"},"finish_reason":null}],"usage":null,"obfuscation":"UC8yn7OQ"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" across"},"finish_reason":null}],"usage":null,"obfuscation":"luOry"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"finish_reason":null}],"usage":null,"obfuscation":"k2wtvoxAkv"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" purple"},"finish_reason":null}],"usage":null,"obfuscation":"MJ2Yn"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" background"},"finish_reason":null}],"usage":null,"obfuscation":"x"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":","},"finish_reason":null}],"usage":null,"obfuscation":"Q9c8GDMUB8Y"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" leaving"},"finish_reason":null}],"usage":null,"obfuscation":"Lodx"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"finish_reason":null}],"usage":null,"obfuscation":"pFKlcPcImA"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" pastel"},"finish_reason":null}],"usage":null,"obfuscation":"6je3F"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" rainbow"},"finish_reason":null}],"usage":null,"obfuscation":"inA3"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" trail"},"finish_reason":null}],"usage":null,"obfuscation":"CXnkhv"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" and"},"finish_reason":null}],"usage":null,"obfuscation":"27rhi5QH"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" spark"},"finish_reason":null}],"usage":null,"obfuscation":"ydh6YX"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"les"},"finish_reason":null}],"usage":null,"obfuscation":"DobyxEtid"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"finish_reason":null}],"usage":null,"obfuscation":"bReSLaCxorF"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":null,"obfuscation":"Jdcmk3"}
+
+ data: {"id":"chatcmpl-CSjPPcAP5y1QNMmqqfd0YirKuEJSB","object":"chat.completion.chunk","created":1760963771,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":232,"completion_tokens":32,"total_tokens":264,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"FTTetrIYY"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 2.69550725s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/multi_tool.yaml
new file mode 100644
index 000000000..11fb20471
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/multi_tool.yaml
@@ -0,0 +1,153 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 816
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"gpt-4o-mini","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdyxdsCExOS7bMCJ0q5fBEN9lCYM",
+ "object": "chat.completion",
+ "created": 1760704583,
+ "model": "gpt-4o-mini-2024-07-18",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": null,
+ "tool_calls": [
+ {
+ "id": "call_H0yMeWt85QiaFMjrlPqAyCYY",
+ "type": "function",
+ "function": {
+ "name": "add",
+ "arguments": "{\"a\": 2, \"b\": 3}"
+ }
+ },
+ {
+ "id": "call_Xh3xOMoQueLZUgW7HYVvwwql",
+ "type": "function",
+ "function": {
+ "name": "multiply",
+ "arguments": "{\"a\": 2, \"b\": 3}"
+ }
+ }
+ ],
+ "refusal": null,
+ "annotations": []
+ },
+ "logprobs": null,
+ "finish_reason": "tool_calls"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 110,
+ "completion_tokens": 50,
+ "total_tokens": 160,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 0,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": "fp_560af6e559"
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.030219167s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1247
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_H0yMeWt85QiaFMjrlPqAyCYY","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"call_Xh3xOMoQueLZUgW7HYVvwwql","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"call_H0yMeWt85QiaFMjrlPqAyCYY","role":"tool"},{"content":"6","tool_call_id":"call_Xh3xOMoQueLZUgW7HYVvwwql","role":"tool"}],"model":"gpt-4o-mini","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdyzVF8CB8APitB5WP6J9QSdWilT",
+ "object": "chat.completion",
+ "created": 1760704585,
+ "model": "gpt-4o-mini-2024-07-18",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "The result of adding 2 and 3 is 5, and the result of multiplying 2 and 3 is 6.",
+ "refusal": null,
+ "annotations": []
+ },
+ "logprobs": null,
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 176,
+ "completion_tokens": 28,
+ "total_tokens": 204,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 0,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": "fp_560af6e559"
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 987.804708ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/multi_tool_streaming.yaml
new file mode 100644
index 000000000..cbf4d3537
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/multi_tool_streaming.yaml
@@ -0,0 +1,147 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 853
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"gpt-4o-mini","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdz0aS9mqbcyCuvqkNMoVXDUraLn","object":"chat.completion.chunk","created":1760704586,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}],"obfuscation":"icfARx"}
+
+ data: {"id":"chatcmpl-CRdz0aS9mqbcyCuvqkNMoVXDUraLn","object":"chat.completion.chunk","created":1760704586,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_vgTL4QSVMl9ocwrlDENBvKCl","type":"function","function":{"name":"add","arguments":""}}]},"logprobs":null,"finish_reason":null}],"obfuscation":"feBbOJXFBL4EO"}
+
+ data: {"id":"chatcmpl-CRdz0aS9mqbcyCuvqkNMoVXDUraLn","object":"chat.completion.chunk","created":1760704586,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"a\""}}]},"logprobs":null,"finish_reason":null}],"obfuscation":"VkgJFOcIZbR"}
+
+ data: {"id":"chatcmpl-CRdz0aS9mqbcyCuvqkNMoVXDUraLn","object":"chat.completion.chunk","created":1760704586,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":": 2, "}}]},"logprobs":null,"finish_reason":null}],"obfuscation":"3w2natY0RoGc"}
+
+ data: {"id":"chatcmpl-CRdz0aS9mqbcyCuvqkNMoVXDUraLn","object":"chat.completion.chunk","created":1760704586,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"b\": 3"}}]},"logprobs":null,"finish_reason":null}],"obfuscation":"36y1gHQIT"}
+
+ data: {"id":"chatcmpl-CRdz0aS9mqbcyCuvqkNMoVXDUraLn","object":"chat.completion.chunk","created":1760704586,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"}"}}]},"logprobs":null,"finish_reason":null}],"obfuscation":""}
+
+ data: {"id":"chatcmpl-CRdz0aS9mqbcyCuvqkNMoVXDUraLn","object":"chat.completion.chunk","created":1760704586,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_0163ysRAfpd1kX8JEsq8piJv","type":"function","function":{"name":"multiply","arguments":""}}]},"logprobs":null,"finish_reason":null}],"obfuscation":"dWNz2rVl"}
+
+ data: {"id":"chatcmpl-CRdz0aS9mqbcyCuvqkNMoVXDUraLn","object":"chat.completion.chunk","created":1760704586,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"a\""}}]},"logprobs":null,"finish_reason":null}],"obfuscation":"ko1uYx2756e"}
+
+ data: {"id":"chatcmpl-CRdz0aS9mqbcyCuvqkNMoVXDUraLn","object":"chat.completion.chunk","created":1760704586,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":": 2, "}}]},"logprobs":null,"finish_reason":null}],"obfuscation":"8ty7XqR7h2EW"}
+
+ data: {"id":"chatcmpl-CRdz0aS9mqbcyCuvqkNMoVXDUraLn","object":"chat.completion.chunk","created":1760704586,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"\"b\": 3"}}]},"logprobs":null,"finish_reason":null}],"obfuscation":"iD4RWBFbS"}
+
+ data: {"id":"chatcmpl-CRdz0aS9mqbcyCuvqkNMoVXDUraLn","object":"chat.completion.chunk","created":1760704586,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"}"}}]},"logprobs":null,"finish_reason":null}],"obfuscation":""}
+
+ data: {"id":"chatcmpl-CRdz0aS9mqbcyCuvqkNMoVXDUraLn","object":"chat.completion.chunk","created":1760704586,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null,"obfuscation":"vknFSfxKgFJlLl9"}
+
+ data: {"id":"chatcmpl-CRdz0aS9mqbcyCuvqkNMoVXDUraLn","object":"chat.completion.chunk","created":1760704586,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[],"usage":{"prompt_tokens":106,"completion_tokens":50,"total_tokens":156,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"hms0Yf0n"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.538896292s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1284
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_vgTL4QSVMl9ocwrlDENBvKCl","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"call_0163ysRAfpd1kX8JEsq8piJv","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"call_vgTL4QSVMl9ocwrlDENBvKCl","role":"tool"},{"content":"6","tool_call_id":"call_0163ysRAfpd1kX8JEsq8piJv","role":"tool"}],"model":"gpt-4o-mini","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"6SLbBHqzK"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"q75QdzGc"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" sum"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"JkSJSpe"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Fi2wspyk"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"RXvBB9PXzG"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"2"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ujYHkroCfT"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ITQLTFp"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"E7m6MjfMt3"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"DRYRaSiTRa"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"nqa6qObb"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"y4ntGcWHia"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"5"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Oqqu6A6xuL"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"KJoWB4TVlb"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"vkqbtjX"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"QS86hO5"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" product"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"FJu"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Ro4WzpG2"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"oCIJrrf6Bp"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"2"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"F10Kbuq9sR"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"MM5G9Kp"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"XTzTNroRtq"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"xGzeZa2yza"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"N6A8H4NU"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"mS71DW3IyN"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"6"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"mCm2RXW0k6"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"GQdrwWteKo"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"416kd"}
+
+ data: {"id":"chatcmpl-CRdz21hccnb76Tjoh5ZtYfJ7qUcKS","object":"chat.completion.chunk","created":1760704588,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[],"usage":{"prompt_tokens":172,"completion_tokens":26,"total_tokens":198,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"JbBHLqxI"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 737.127958ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/simple.yaml
new file mode 100644
index 000000000..1d267cf1c
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/simple.yaml
@@ -0,0 +1,69 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 161
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"gpt-4o-mini","max_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdysIxOQVTFiu9TMRyxiiYHHQyTj",
+ "object": "chat.completion",
+ "created": 1760704578,
+ "model": "gpt-4o-mini-2024-07-18",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "OlĆ”!",
+ "refusal": null,
+ "annotations": []
+ },
+ "logprobs": null,
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 20,
+ "completion_tokens": 2,
+ "total_tokens": 22,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 0,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": "fp_560af6e559"
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 902.366208ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/simple_streaming.yaml
new file mode 100644
index 000000000..f27ef6258
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/simple_streaming.yaml
@@ -0,0 +1,60 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 215
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"gpt-4o-mini","max_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdytk5LO0hrSMS9Co5OPHLFCuLSF","object":"chat.completion.chunk","created":1760704579,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"dNrgk6KCj"}
+
+ data: {"id":"chatcmpl-CRdytk5LO0hrSMS9Co5OPHLFCuLSF","object":"chat.completion.chunk","created":1760704579,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"Hi"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"wRjU25PHG"}
+
+ data: {"id":"chatcmpl-CRdytk5LO0hrSMS9Co5OPHLFCuLSF","object":"chat.completion.chunk","created":1760704579,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"!"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"li6Xgje1BS"}
+
+ data: {"id":"chatcmpl-CRdytk5LO0hrSMS9Co5OPHLFCuLSF","object":"chat.completion.chunk","created":1760704579,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" In"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"3rRemht7"}
+
+ data: {"id":"chatcmpl-CRdytk5LO0hrSMS9Co5OPHLFCuLSF","object":"chat.completion.chunk","created":1760704579,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" Portuguese"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":""}
+
+ data: {"id":"chatcmpl-CRdytk5LO0hrSMS9Co5OPHLFCuLSF","object":"chat.completion.chunk","created":1760704579,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"S0Wp8u71lq"}
+
+ data: {"id":"chatcmpl-CRdytk5LO0hrSMS9Co5OPHLFCuLSF","object":"chat.completion.chunk","created":1760704579,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"gsbpPtV"}
+
+ data: {"id":"chatcmpl-CRdytk5LO0hrSMS9Co5OPHLFCuLSF","object":"chat.completion.chunk","created":1760704579,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" say"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"LBoNQFN"}
+
+ data: {"id":"chatcmpl-CRdytk5LO0hrSMS9Co5OPHLFCuLSF","object":"chat.completion.chunk","created":1760704579,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" \""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Bgm7GOfe"}
+
+ data: {"id":"chatcmpl-CRdytk5LO0hrSMS9Co5OPHLFCuLSF","object":"chat.completion.chunk","created":1760704579,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"OlĆ”"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"CmJzapI9"}
+
+ data: {"id":"chatcmpl-CRdytk5LO0hrSMS9Co5OPHLFCuLSF","object":"chat.completion.chunk","created":1760704579,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"!\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"dtukc2xn"}
+
+ data: {"id":"chatcmpl-CRdytk5LO0hrSMS9Co5OPHLFCuLSF","object":"chat.completion.chunk","created":1760704579,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"nYn46"}
+
+ data: {"id":"chatcmpl-CRdytk5LO0hrSMS9Co5OPHLFCuLSF","object":"chat.completion.chunk","created":1760704579,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[],"usage":{"prompt_tokens":20,"completion_tokens":10,"total_tokens":30,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"wXXaHiliFF"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 566.636417ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/tool.yaml
new file mode 100644
index 000000000..8e7ec09a5
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/tool.yaml
@@ -0,0 +1,145 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 453
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"gpt-4o-mini","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdyuS0DEOR3GgR76SLPKqPiwPIAt",
+ "object": "chat.completion",
+ "created": 1760704580,
+ "model": "gpt-4o-mini-2024-07-18",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": null,
+ "tool_calls": [
+ {
+ "id": "call_2uH56RhZZbC8djqCn7cxRyKl",
+ "type": "function",
+ "function": {
+ "name": "weather",
+ "arguments": "{\"location\":\"Florence, Italy\"}"
+ }
+ }
+ ],
+ "refusal": null,
+ "annotations": []
+ },
+ "logprobs": null,
+ "finish_reason": "tool_calls"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 61,
+ "completion_tokens": 16,
+ "total_tokens": 77,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 0,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": "fp_560af6e559"
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.057664375s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 705
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_2uH56RhZZbC8djqCn7cxRyKl","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_2uH56RhZZbC8djqCn7cxRyKl","role":"tool"}],"model":"gpt-4o-mini","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdyvMVFPOfa2G1IC80Js9jy1xIE0",
+ "object": "chat.completion",
+ "created": 1760704581,
+ "model": "gpt-4o-mini-2024-07-18",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "The weather in Florence, Italy is currently 40°C.",
+ "refusal": null,
+ "annotations": []
+ },
+ "logprobs": null,
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 86,
+ "completion_tokens": 13,
+ "total_tokens": 99,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 0,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": "fp_560af6e559"
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 933.192292ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/tool_streaming.yaml
new file mode 100644
index 000000000..2fc71eadd
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o-mini/tool_streaming.yaml
@@ -0,0 +1,117 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 507
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"gpt-4o-mini","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdywA4dbuMAJLXVP860cVgCKV8Jz","object":"chat.completion.chunk","created":1760704582,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"call_eOpGKcIP7rzEsLNRtEm9K6mx","type":"function","function":{"name":"weather","arguments":""}}],"refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"M7LBWEuz"}
+
+ data: {"id":"chatcmpl-CRdywA4dbuMAJLXVP860cVgCKV8Jz","object":"chat.completion.chunk","created":1760704582,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\""}}]},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"y0wRfvzAfc7Gwp"}
+
+ data: {"id":"chatcmpl-CRdywA4dbuMAJLXVP860cVgCKV8Jz","object":"chat.completion.chunk","created":1760704582,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"location"}}]},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"l4ftT9t8s"}
+
+ data: {"id":"chatcmpl-CRdywA4dbuMAJLXVP860cVgCKV8Jz","object":"chat.completion.chunk","created":1760704582,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"egmKNDffXaU3"}
+
+ data: {"id":"chatcmpl-CRdywA4dbuMAJLXVP860cVgCKV8Jz","object":"chat.completion.chunk","created":1760704582,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Flor"}}]},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"GG1ybnr1YrkNG"}
+
+ data: {"id":"chatcmpl-CRdywA4dbuMAJLXVP860cVgCKV8Jz","object":"chat.completion.chunk","created":1760704582,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"ence"}}]},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"bSU8KmpVhJmCU"}
+
+ data: {"id":"chatcmpl-CRdywA4dbuMAJLXVP860cVgCKV8Jz","object":"chat.completion.chunk","created":1760704582,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":","}}]},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":""}
+
+ data: {"id":"chatcmpl-CRdywA4dbuMAJLXVP860cVgCKV8Jz","object":"chat.completion.chunk","created":1760704582,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" Italy"}}]},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"iRxnuJP3cpr"}
+
+ data: {"id":"chatcmpl-CRdywA4dbuMAJLXVP860cVgCKV8Jz","object":"chat.completion.chunk","created":1760704582,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"}"}}]},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"QBAmqhvyRFjbCZ"}
+
+ data: {"id":"chatcmpl-CRdywA4dbuMAJLXVP860cVgCKV8Jz","object":"chat.completion.chunk","created":1760704582,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null,"obfuscation":"3ebmRJY6jIoVVSq"}
+
+ data: {"id":"chatcmpl-CRdywA4dbuMAJLXVP860cVgCKV8Jz","object":"chat.completion.chunk","created":1760704582,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[],"usage":{"prompt_tokens":61,"completion_tokens":16,"total_tokens":77,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"9htLycow0a"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 680.827667ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 759
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_eOpGKcIP7rzEsLNRtEm9K6mx","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_eOpGKcIP7rzEsLNRtEm9K6mx","role":"tool"}],"model":"gpt-4o-mini","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdyx1hGexd66KC0T4iMnborWhkbJ","object":"chat.completion.chunk","created":1760704583,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"uB0vXwmAg"}
+
+ data: {"id":"chatcmpl-CRdyx1hGexd66KC0T4iMnborWhkbJ","object":"chat.completion.chunk","created":1760704583,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"bXKWncif"}
+
+ data: {"id":"chatcmpl-CRdyx1hGexd66KC0T4iMnborWhkbJ","object":"chat.completion.chunk","created":1760704583,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"5VH"}
+
+ data: {"id":"chatcmpl-CRdyx1hGexd66KC0T4iMnborWhkbJ","object":"chat.completion.chunk","created":1760704583,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"cOVYqBuN"}
+
+ data: {"id":"chatcmpl-CRdyx1hGexd66KC0T4iMnborWhkbJ","object":"chat.completion.chunk","created":1760704583,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" Florence"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"qn"}
+
+ data: {"id":"chatcmpl-CRdyx1hGexd66KC0T4iMnborWhkbJ","object":"chat.completion.chunk","created":1760704583,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ETVXMoB3wo"}
+
+ data: {"id":"chatcmpl-CRdyx1hGexd66KC0T4iMnborWhkbJ","object":"chat.completion.chunk","created":1760704583,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" Italy"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"TJueB"}
+
+ data: {"id":"chatcmpl-CRdyx1hGexd66KC0T4iMnborWhkbJ","object":"chat.completion.chunk","created":1760704583,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"2dXikvHR"}
+
+ data: {"id":"chatcmpl-CRdyx1hGexd66KC0T4iMnborWhkbJ","object":"chat.completion.chunk","created":1760704583,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" currently"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"U"}
+
+ data: {"id":"chatcmpl-CRdyx1hGexd66KC0T4iMnborWhkbJ","object":"chat.completion.chunk","created":1760704583,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"SJvYbm15DI"}
+
+ data: {"id":"chatcmpl-CRdyx1hGexd66KC0T4iMnborWhkbJ","object":"chat.completion.chunk","created":1760704583,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"40"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"MmF8rVRCD"}
+
+ data: {"id":"chatcmpl-CRdyx1hGexd66KC0T4iMnborWhkbJ","object":"chat.completion.chunk","created":1760704583,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"°C"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"6apyDO2Sn"}
+
+ data: {"id":"chatcmpl-CRdyx1hGexd66KC0T4iMnborWhkbJ","object":"chat.completion.chunk","created":1760704583,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"10hdWpCjhh"}
+
+ data: {"id":"chatcmpl-CRdyx1hGexd66KC0T4iMnborWhkbJ","object":"chat.completion.chunk","created":1760704583,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"CFuXa"}
+
+ data: {"id":"chatcmpl-CRdyx1hGexd66KC0T4iMnborWhkbJ","object":"chat.completion.chunk","created":1760704583,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[],"usage":{"prompt_tokens":86,"completion_tokens":13,"total_tokens":99,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"G7mYdCwtgy"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 434.186417ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/multi_tool.yaml
new file mode 100644
index 000000000..dc675015a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/multi_tool.yaml
@@ -0,0 +1,153 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 811
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"gpt-4o","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdyoWcDq406PCUaEpBjaiqUGhoI3",
+ "object": "chat.completion",
+ "created": 1760704574,
+ "model": "gpt-4o-2024-08-06",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": null,
+ "tool_calls": [
+ {
+ "id": "call_Cg9itjRbJ4NYAZEbIwcSiEJZ",
+ "type": "function",
+ "function": {
+ "name": "add",
+ "arguments": "{\"a\": 2, \"b\": 3}"
+ }
+ },
+ {
+ "id": "call_sSIhNbcU2Ap95fBjcsScrTMz",
+ "type": "function",
+ "function": {
+ "name": "multiply",
+ "arguments": "{\"a\": 2, \"b\": 3}"
+ }
+ }
+ ],
+ "refusal": null,
+ "annotations": []
+ },
+ "logprobs": null,
+ "finish_reason": "tool_calls"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 110,
+ "completion_tokens": 50,
+ "total_tokens": 160,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 0,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": "fp_f64f290af2"
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.503138709s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1242
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_Cg9itjRbJ4NYAZEbIwcSiEJZ","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"call_sSIhNbcU2Ap95fBjcsScrTMz","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"call_Cg9itjRbJ4NYAZEbIwcSiEJZ","role":"tool"},{"content":"6","tool_call_id":"call_sSIhNbcU2Ap95fBjcsScrTMz","role":"tool"}],"model":"gpt-4o","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdyq4Im6cnYdhDwDtM3utmxVrohv",
+ "object": "chat.completion",
+ "created": 1760704576,
+ "model": "gpt-4o-2024-08-06",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "The result of adding 2 and 3 is 5, and the result of multiplying 2 and 3 is 6.",
+ "refusal": null,
+ "annotations": []
+ },
+ "logprobs": null,
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 176,
+ "completion_tokens": 28,
+ "total_tokens": 204,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 0,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": "fp_f64f290af2"
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 632.902333ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/multi_tool_streaming.yaml
new file mode 100644
index 000000000..23f237bbf
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/multi_tool_streaming.yaml
@@ -0,0 +1,135 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 848
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"gpt-4o","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdyrlpgfyiFlAAnoiflUbvXhNUGP","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}],"obfuscation":"OHGcRuhO4A4"}
+
+ data: {"id":"chatcmpl-CRdyrlpgfyiFlAAnoiflUbvXhNUGP","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_43EjiXfsjRlSfqUDWptDvMBZ","type":"function","function":{"name":"add","arguments":""}}]},"logprobs":null,"finish_reason":null}],"obfuscation":"Zz"}
+
+ data: {"id":"chatcmpl-CRdyrlpgfyiFlAAnoiflUbvXhNUGP","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"a\""}}]},"logprobs":null,"finish_reason":null}],"obfuscation":""}
+
+ data: {"id":"chatcmpl-CRdyrlpgfyiFlAAnoiflUbvXhNUGP","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":": 2, "}}]},"logprobs":null,"finish_reason":null}],"obfuscation":"X"}
+
+ data: {"id":"chatcmpl-CRdyrlpgfyiFlAAnoiflUbvXhNUGP","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"b\": 3"}}]},"logprobs":null,"finish_reason":null}],"obfuscation":"m5lvJ0jw20BTZs"}
+
+ data: {"id":"chatcmpl-CRdyrlpgfyiFlAAnoiflUbvXhNUGP","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"}"}}]},"logprobs":null,"finish_reason":null}],"obfuscation":"uM0Ca"}
+
+ data: {"id":"chatcmpl-CRdyrlpgfyiFlAAnoiflUbvXhNUGP","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_xHjbYtQqq9gsbadfjB3Vpjde","type":"function","function":{"name":"multiply","arguments":""}}]},"logprobs":null,"finish_reason":null}],"obfuscation":"u39m7n3pFddmq"}
+
+ data: {"id":"chatcmpl-CRdyrlpgfyiFlAAnoiflUbvXhNUGP","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"a\""}}]},"logprobs":null,"finish_reason":null}],"obfuscation":""}
+
+ data: {"id":"chatcmpl-CRdyrlpgfyiFlAAnoiflUbvXhNUGP","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":": 2, "}}]},"logprobs":null,"finish_reason":null}],"obfuscation":"Z"}
+
+ data: {"id":"chatcmpl-CRdyrlpgfyiFlAAnoiflUbvXhNUGP","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"\"b\": 3"}}]},"logprobs":null,"finish_reason":null}],"obfuscation":"fk12n2in3eYPHY"}
+
+ data: {"id":"chatcmpl-CRdyrlpgfyiFlAAnoiflUbvXhNUGP","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"}"}}]},"logprobs":null,"finish_reason":null}],"obfuscation":"XS0QR"}
+
+ data: {"id":"chatcmpl-CRdyrlpgfyiFlAAnoiflUbvXhNUGP","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null,"obfuscation":"J1Fr"}
+
+ data: {"id":"chatcmpl-CRdyrlpgfyiFlAAnoiflUbvXhNUGP","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[],"usage":{"prompt_tokens":106,"completion_tokens":50,"total_tokens":156,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"8X9w9cqTHQGUY"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 772.991416ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1279
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_43EjiXfsjRlSfqUDWptDvMBZ","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"call_xHjbYtQqq9gsbadfjB3Vpjde","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"call_43EjiXfsjRlSfqUDWptDvMBZ","role":"tool"},{"content":"6","tool_call_id":"call_xHjbYtQqq9gsbadfjB3Vpjde","role":"tool"}],"model":"gpt-4o","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"wQ0ZUR76SWLb1Q"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ISPfkxMctrH0o"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" sum"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"JqFwg751miTx"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"9YWR8giqtYFUM"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"itlKS7ahTpMBW8L"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"2"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"2e7u7BIkx92l3cr"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"m5Oplb1gN9Ja"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"3vugZRR3s2aEKKY"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"28sBUXYUnGB22UI"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"AuXkgVuyVW8Hy"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"PJgz1kJnoOj9Ftb"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"5"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"5osDSc1ClKxMw71"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"QsS9PzfMEQOkIt4"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"qfFoD9BWS7OJ"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"yVmAXLCiwmCA"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" product"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"zdqgWQg4"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"BURYwy2cPdNM1"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"z12QGfGlmG9qbx1"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"6"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"WLygsVccLgfco4Q"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"gK83HveBSnYrHmO"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"AmG4YiCc1W"}
+
+ data: {"id":"chatcmpl-CRdyriuRwApMtbM90UU0ea8z83pmx","object":"chat.completion.chunk","created":1760704577,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[],"usage":{"prompt_tokens":172,"completion_tokens":20,"total_tokens":192,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"BlFvM9v7xKitB"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 582.337667ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/simple.yaml
new file mode 100644
index 000000000..1199b98bc
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/simple.yaml
@@ -0,0 +1,69 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 156
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"gpt-4o","max_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdyjdJswbbI6kuVNScObDe3tYnu2",
+ "object": "chat.completion",
+ "created": 1760704569,
+ "model": "gpt-4o-2024-08-06",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "OlĆ”!",
+ "refusal": null,
+ "annotations": []
+ },
+ "logprobs": null,
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 20,
+ "completion_tokens": 2,
+ "total_tokens": 22,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 0,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": "fp_cbf1785567"
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 740.354167ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/simple_streaming.yaml
new file mode 100644
index 000000000..9c31b3f73
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/simple_streaming.yaml
@@ -0,0 +1,44 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 210
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"gpt-4o","max_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdyjrv70pWoCSnjiX81dksuhZK0H","object":"chat.completion.chunk","created":1760704569,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"dW8LjvG3FnxHr9"}
+
+ data: {"id":"chatcmpl-CRdyjrv70pWoCSnjiX81dksuhZK0H","object":"chat.completion.chunk","created":1760704569,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"OlĆ”"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"HhaSik3KUWGzk"}
+
+ data: {"id":"chatcmpl-CRdyjrv70pWoCSnjiX81dksuhZK0H","object":"chat.completion.chunk","created":1760704569,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"!"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"XoNpCCkgDMpPelm"}
+
+ data: {"id":"chatcmpl-CRdyjrv70pWoCSnjiX81dksuhZK0H","object":"chat.completion.chunk","created":1760704569,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"FbHAsgWpZy"}
+
+ data: {"id":"chatcmpl-CRdyjrv70pWoCSnjiX81dksuhZK0H","object":"chat.completion.chunk","created":1760704569,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[],"usage":{"prompt_tokens":20,"completion_tokens":2,"total_tokens":22,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":""}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 626.391292ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/tool.yaml
new file mode 100644
index 000000000..2f58ff98e
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/tool.yaml
@@ -0,0 +1,145 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 448
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"gpt-4o","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdykecyitTrtBgxG3cAhHM82R3ar",
+ "object": "chat.completion",
+ "created": 1760704570,
+ "model": "gpt-4o-2024-08-06",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": null,
+ "tool_calls": [
+ {
+ "id": "call_zKl0GvROtopAKaVzafvOYfPu",
+ "type": "function",
+ "function": {
+ "name": "weather",
+ "arguments": "{\"location\":\"Florence, Italy\"}"
+ }
+ }
+ ],
+ "refusal": null,
+ "annotations": []
+ },
+ "logprobs": null,
+ "finish_reason": "tool_calls"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 61,
+ "completion_tokens": 16,
+ "total_tokens": 77,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 0,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": "fp_cbf1785567"
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.142721375s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 700
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_zKl0GvROtopAKaVzafvOYfPu","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_zKl0GvROtopAKaVzafvOYfPu","role":"tool"}],"model":"gpt-4o","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdyljyj1IrCMsT69QVozUugzhlwd",
+ "object": "chat.completion",
+ "created": 1760704571,
+ "model": "gpt-4o-2024-08-06",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "The current temperature in Florence, Italy is 40°C.",
+ "refusal": null,
+ "annotations": []
+ },
+ "logprobs": null,
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 86,
+ "completion_tokens": 13,
+ "total_tokens": 99,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 0,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": "fp_cbf1785567"
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.414555709s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/tool_streaming.yaml
new file mode 100644
index 000000000..047631066
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-4o/tool_streaming.yaml
@@ -0,0 +1,117 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 502
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"gpt-4o","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdynEXtk7T39drPlGlAxtuaMPYtO","object":"chat.completion.chunk","created":1760704573,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"call_9W0PDPMmK2SHo8Ph5qmngr60","type":"function","function":{"name":"weather","arguments":""}}],"refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"SKTBYmVhUa37r"}
+
+ data: {"id":"chatcmpl-CRdynEXtk7T39drPlGlAxtuaMPYtO","object":"chat.completion.chunk","created":1760704573,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\""}}]},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ISP"}
+
+ data: {"id":"chatcmpl-CRdynEXtk7T39drPlGlAxtuaMPYtO","object":"chat.completion.chunk","created":1760704573,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"location"}}]},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"wTarJRBKmxWzEe"}
+
+ data: {"id":"chatcmpl-CRdynEXtk7T39drPlGlAxtuaMPYtO","object":"chat.completion.chunk","created":1760704573,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"b"}
+
+ data: {"id":"chatcmpl-CRdynEXtk7T39drPlGlAxtuaMPYtO","object":"chat.completion.chunk","created":1760704573,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Flor"}}]},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Dt"}
+
+ data: {"id":"chatcmpl-CRdynEXtk7T39drPlGlAxtuaMPYtO","object":"chat.completion.chunk","created":1760704573,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"ence"}}]},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"lK"}
+
+ data: {"id":"chatcmpl-CRdynEXtk7T39drPlGlAxtuaMPYtO","object":"chat.completion.chunk","created":1760704573,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":","}}]},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ZEEqt"}
+
+ data: {"id":"chatcmpl-CRdynEXtk7T39drPlGlAxtuaMPYtO","object":"chat.completion.chunk","created":1760704573,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" Italy"}}]},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":""}
+
+ data: {"id":"chatcmpl-CRdynEXtk7T39drPlGlAxtuaMPYtO","object":"chat.completion.chunk","created":1760704573,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"}"}}]},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"tsM"}
+
+ data: {"id":"chatcmpl-CRdynEXtk7T39drPlGlAxtuaMPYtO","object":"chat.completion.chunk","created":1760704573,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null,"obfuscation":"hAQV"}
+
+ data: {"id":"chatcmpl-CRdynEXtk7T39drPlGlAxtuaMPYtO","object":"chat.completion.chunk","created":1760704573,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[],"usage":{"prompt_tokens":61,"completion_tokens":16,"total_tokens":77,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"1fPE9DL5GVNekQj"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 828.397667ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 754
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_9W0PDPMmK2SHo8Ph5qmngr60","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_9W0PDPMmK2SHo8Ph5qmngr60","role":"tool"}],"model":"gpt-4o","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdyomJ9SewTkG1C99SPqHd6NWByb","object":"chat.completion.chunk","created":1760704574,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"redbGckJxoV9Sf"}
+
+ data: {"id":"chatcmpl-CRdyomJ9SewTkG1C99SPqHd6NWByb","object":"chat.completion.chunk","created":1760704574,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"hokBzzfi9soMV"}
+
+ data: {"id":"chatcmpl-CRdyomJ9SewTkG1C99SPqHd6NWByb","object":"chat.completion.chunk","created":1760704574,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" current"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"GYmp4NHd"}
+
+ data: {"id":"chatcmpl-CRdyomJ9SewTkG1C99SPqHd6NWByb","object":"chat.completion.chunk","created":1760704574,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" temperature"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"V72K"}
+
+ data: {"id":"chatcmpl-CRdyomJ9SewTkG1C99SPqHd6NWByb","object":"chat.completion.chunk","created":1760704574,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"J4dE5Y0oVkTnc"}
+
+ data: {"id":"chatcmpl-CRdyomJ9SewTkG1C99SPqHd6NWByb","object":"chat.completion.chunk","created":1760704574,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" Florence"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"embLD68"}
+
+ data: {"id":"chatcmpl-CRdyomJ9SewTkG1C99SPqHd6NWByb","object":"chat.completion.chunk","created":1760704574,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"QxOjL2vP9UUb8DE"}
+
+ data: {"id":"chatcmpl-CRdyomJ9SewTkG1C99SPqHd6NWByb","object":"chat.completion.chunk","created":1760704574,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" Italy"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"xVq2JhUM0m"}
+
+ data: {"id":"chatcmpl-CRdyomJ9SewTkG1C99SPqHd6NWByb","object":"chat.completion.chunk","created":1760704574,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"wR1prrEQ6cTc3"}
+
+ data: {"id":"chatcmpl-CRdyomJ9SewTkG1C99SPqHd6NWByb","object":"chat.completion.chunk","created":1760704574,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"8tMP4q2OCLlkRy3"}
+
+ data: {"id":"chatcmpl-CRdyomJ9SewTkG1C99SPqHd6NWByb","object":"chat.completion.chunk","created":1760704574,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"40"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"GOjJVxLP9sk8u4"}
+
+ data: {"id":"chatcmpl-CRdyomJ9SewTkG1C99SPqHd6NWByb","object":"chat.completion.chunk","created":1760704574,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"°C"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"CCwAe3AFhmdpna"}
+
+ data: {"id":"chatcmpl-CRdyomJ9SewTkG1C99SPqHd6NWByb","object":"chat.completion.chunk","created":1760704574,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"6DQeIz589eDMca5"}
+
+ data: {"id":"chatcmpl-CRdyomJ9SewTkG1C99SPqHd6NWByb","object":"chat.completion.chunk","created":1760704574,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"gnoMeZSJgE"}
+
+ data: {"id":"chatcmpl-CRdyomJ9SewTkG1C99SPqHd6NWByb","object":"chat.completion.chunk","created":1760704574,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[],"usage":{"prompt_tokens":86,"completion_tokens":13,"total_tokens":99,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"ImGWeSBRNjxx71V"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 637.852666ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/multi_tool.yaml
new file mode 100644
index 000000000..ded49c07c
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/multi_tool.yaml
@@ -0,0 +1,151 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 821
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"gpt-5","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdzUDVMIrCJUYwgqR69TFp8L2Swc",
+ "object": "chat.completion",
+ "created": 1760704616,
+ "model": "gpt-5-2025-08-07",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": null,
+ "tool_calls": [
+ {
+ "id": "call_md2XuaM6Rk2D4bTo2L6U2rC4",
+ "type": "function",
+ "function": {
+ "name": "add",
+ "arguments": "{\"a\": 2, \"b\": 3}"
+ }
+ },
+ {
+ "id": "call_uSejWXP98W4wT6BU62WnSFkD",
+ "type": "function",
+ "function": {
+ "name": "multiply",
+ "arguments": "{\"a\": 2, \"b\": 3}"
+ }
+ }
+ ],
+ "refusal": null,
+ "annotations": []
+ },
+ "finish_reason": "tool_calls"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 194,
+ "completion_tokens": 315,
+ "total_tokens": 509,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 256,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": null
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 5.788909416s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1252
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_md2XuaM6Rk2D4bTo2L6U2rC4","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"call_uSejWXP98W4wT6BU62WnSFkD","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"call_md2XuaM6Rk2D4bTo2L6U2rC4","role":"tool"},{"content":"6","tool_call_id":"call_uSejWXP98W4wT6BU62WnSFkD","role":"tool"}],"model":"gpt-5","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdzaC6UTwNAIUssvUroMMI05yZPC",
+ "object": "chat.completion",
+ "created": 1760704622,
+ "model": "gpt-5-2025-08-07",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "- Sum (2 + 3): 5\n- Product (2 Ć 3): 6",
+ "refusal": null,
+ "annotations": []
+ },
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 266,
+ "completion_tokens": 24,
+ "total_tokens": 290,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 0,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": null
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.555093917s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/multi_tool_streaming.yaml
new file mode 100644
index 000000000..858a42df1
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/multi_tool_streaming.yaml
@@ -0,0 +1,143 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 858
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdzc7GhPT7mc2HunXDSslDWG7Bhx","object":"chat.completion.chunk","created":1760704624,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"finish_reason":null}],"obfuscation":"NvBRsp2"}
+
+ data: {"id":"chatcmpl-CRdzc7GhPT7mc2HunXDSslDWG7Bhx","object":"chat.completion.chunk","created":1760704624,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_4ebZx1iZmHY4sPZ1h1iMHaWD","type":"function","function":{"name":"add","arguments":""}}]},"finish_reason":null}],"obfuscation":"5qQkfsMd6Ydd9V"}
+
+ data: {"id":"chatcmpl-CRdzc7GhPT7mc2HunXDSslDWG7Bhx","object":"chat.completion.chunk","created":1760704624,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"a\""}}]},"finish_reason":null}],"obfuscation":"VeWK0cIPeocT"}
+
+ data: {"id":"chatcmpl-CRdzc7GhPT7mc2HunXDSslDWG7Bhx","object":"chat.completion.chunk","created":1760704624,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":": 2, "}}]},"finish_reason":null}],"obfuscation":"ROMuHEfrgbrS7"}
+
+ data: {"id":"chatcmpl-CRdzc7GhPT7mc2HunXDSslDWG7Bhx","object":"chat.completion.chunk","created":1760704624,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"b\": 3"}}]},"finish_reason":null}],"obfuscation":"xE9kB40afY"}
+
+ data: {"id":"chatcmpl-CRdzc7GhPT7mc2HunXDSslDWG7Bhx","object":"chat.completion.chunk","created":1760704624,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"}"}}]},"finish_reason":null}],"obfuscation":"4"}
+
+ data: {"id":"chatcmpl-CRdzc7GhPT7mc2HunXDSslDWG7Bhx","object":"chat.completion.chunk","created":1760704624,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_wyeHgH870UHPvm0tKc4MwvDD","type":"function","function":{"name":"multiply","arguments":""}}]},"finish_reason":null}],"obfuscation":"IneSneP7z"}
+
+ data: {"id":"chatcmpl-CRdzc7GhPT7mc2HunXDSslDWG7Bhx","object":"chat.completion.chunk","created":1760704624,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"a\""}}]},"finish_reason":null}],"obfuscation":"HGrCNThdZNii"}
+
+ data: {"id":"chatcmpl-CRdzc7GhPT7mc2HunXDSslDWG7Bhx","object":"chat.completion.chunk","created":1760704624,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":": 2, "}}]},"finish_reason":null}],"obfuscation":"5ZULYIdry7hus"}
+
+ data: {"id":"chatcmpl-CRdzc7GhPT7mc2HunXDSslDWG7Bhx","object":"chat.completion.chunk","created":1760704624,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"\"b\": 3"}}]},"finish_reason":null}],"obfuscation":"3iFLy71PX6"}
+
+ data: {"id":"chatcmpl-CRdzc7GhPT7mc2HunXDSslDWG7Bhx","object":"chat.completion.chunk","created":1760704624,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"}"}}]},"finish_reason":null}],"obfuscation":"d"}
+
+ data: {"id":"chatcmpl-CRdzc7GhPT7mc2HunXDSslDWG7Bhx","object":"chat.completion.chunk","created":1760704624,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"usage":null,"obfuscation":""}
+
+ data: {"id":"chatcmpl-CRdzc7GhPT7mc2HunXDSslDWG7Bhx","object":"chat.completion.chunk","created":1760704624,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":190,"completion_tokens":507,"total_tokens":697,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":448,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"Em6PO8"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 7.672726292s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1289
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_4ebZx1iZmHY4sPZ1h1iMHaWD","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"call_wyeHgH870UHPvm0tKc4MwvDD","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"call_4ebZx1iZmHY4sPZ1h1iMHaWD","role":"tool"},{"content":"6","tool_call_id":"call_wyeHgH870UHPvm0tKc4MwvDD","role":"tool"}],"model":"gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"1TG67VBOtJ"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"OHhVbfnddSM"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Sum"},"finish_reason":null}],"usage":null,"obfuscation":"jEUBOH54"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" ("},"finish_reason":null}],"usage":null,"obfuscation":"PtgcMX4qEe"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"2"},"finish_reason":null}],"usage":null,"obfuscation":"zfYlcOcLZ9C"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" +"},"finish_reason":null}],"usage":null,"obfuscation":"1u8xvTtq3Y"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" "},"finish_reason":null}],"usage":null,"obfuscation":"K9I2ZUnGymF"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"3"},"finish_reason":null}],"usage":null,"obfuscation":"TIkXxx9gbCK"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":")"},"finish_reason":null}],"usage":null,"obfuscation":"mFcLz5PLsoF"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" ="},"finish_reason":null}],"usage":null,"obfuscation":"0ZLum9Jw5e"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" "},"finish_reason":null}],"usage":null,"obfuscation":"pbEwyGNzS90"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"5"},"finish_reason":null}],"usage":null,"obfuscation":"OYQfKVWpL6O"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\n"},"finish_reason":null}],"usage":null,"obfuscation":"fjPV5j0VDX"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"j7Xcg9fNM95"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Product"},"finish_reason":null}],"usage":null,"obfuscation":"GAEj"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" ("},"finish_reason":null}],"usage":null,"obfuscation":"BE9tgnurlz"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"2"},"finish_reason":null}],"usage":null,"obfuscation":"Yymwjl7AQga"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Ć"},"finish_reason":null}],"usage":null,"obfuscation":"gGuS8rBmJ7"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" "},"finish_reason":null}],"usage":null,"obfuscation":"8Z5amiIoV0M"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"3"},"finish_reason":null}],"usage":null,"obfuscation":"jBrz8DxKZbt"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":")"},"finish_reason":null}],"usage":null,"obfuscation":"5mWkJRjBkAX"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" ="},"finish_reason":null}],"usage":null,"obfuscation":"UWqBcH386u"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" "},"finish_reason":null}],"usage":null,"obfuscation":"WDsRS72YWt0"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"6"},"finish_reason":null}],"usage":null,"obfuscation":"tUUmtDYNimg"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":null,"obfuscation":"UgDqt8"}
+
+ data: {"id":"chatcmpl-CRdzkO32Hy3VSWpgWF4X77ZM5KD12","object":"chat.completion.chunk","created":1760704632,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":262,"completion_tokens":26,"total_tokens":288,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"Wqu7E2SWz"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 954.683416ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/simple.yaml
new file mode 100644
index 000000000..0e91885c4
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/simple.yaml
@@ -0,0 +1,68 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 166
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"gpt-5","max_completion_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdz3IlGIW2lfJ0VP6n8tkysshWP6",
+ "object": "chat.completion",
+ "created": 1760704589,
+ "model": "gpt-5-2025-08-07",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "Oi!",
+ "refusal": null,
+ "annotations": []
+ },
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 19,
+ "completion_tokens": 203,
+ "total_tokens": 222,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 192,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": null
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 5.250838625s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/simple_streaming.yaml
new file mode 100644
index 000000000..71885f565
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/simple_streaming.yaml
@@ -0,0 +1,44 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 220
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdz8RCAgBM561aJOMPL9YeHB957W","object":"chat.completion.chunk","created":1760704594,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"SFRj4fNgeY"}
+
+ data: {"id":"chatcmpl-CRdz8RCAgBM561aJOMPL9YeHB957W","object":"chat.completion.chunk","created":1760704594,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"OlĆ”"},"finish_reason":null}],"usage":null,"obfuscation":"x2Y1eWqda"}
+
+ data: {"id":"chatcmpl-CRdz8RCAgBM561aJOMPL9YeHB957W","object":"chat.completion.chunk","created":1760704594,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"!"},"finish_reason":null}],"usage":null,"obfuscation":"tDJ7zpDqgTi"}
+
+ data: {"id":"chatcmpl-CRdz8RCAgBM561aJOMPL9YeHB957W","object":"chat.completion.chunk","created":1760704594,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":null,"obfuscation":"85W83X"}
+
+ data: {"id":"chatcmpl-CRdz8RCAgBM561aJOMPL9YeHB957W","object":"chat.completion.chunk","created":1760704594,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":19,"completion_tokens":75,"total_tokens":94,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":64,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"gUl972lllc"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 2.890382667s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/tool.yaml
new file mode 100644
index 000000000..8a8cd3dbe
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/tool.yaml
@@ -0,0 +1,143 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 458
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"gpt-5","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdzCfnkaQoMYKAvfAXds0hUUaCog",
+ "object": "chat.completion",
+ "created": 1760704598,
+ "model": "gpt-5-2025-08-07",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": null,
+ "tool_calls": [
+ {
+ "id": "call_iENK0JiZIVgIwVhzXgr2vqAb",
+ "type": "function",
+ "function": {
+ "name": "weather",
+ "arguments": "{\"location\":\"Florence, Italy\"}"
+ }
+ }
+ ],
+ "refusal": null,
+ "annotations": []
+ },
+ "finish_reason": "tool_calls"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 145,
+ "completion_tokens": 89,
+ "total_tokens": 234,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 64,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": null
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 4.061672083s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 710
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_iENK0JiZIVgIwVhzXgr2vqAb","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_iENK0JiZIVgIwVhzXgr2vqAb","role":"tool"}],"model":"gpt-5","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdzFTi2wOwwtpFFMfez7pGHYh07c",
+ "object": "chat.completion",
+ "created": 1760704601,
+ "model": "gpt-5-2025-08-07",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "Itās currently about 40°C (104°F) in Florence, Italy. Would you like a forecast or more details (humidity, wind, etc.)?",
+ "refusal": null,
+ "annotations": []
+ },
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 176,
+ "completion_tokens": 297,
+ "total_tokens": 473,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 256,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": null
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 6.021670833s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/tool_streaming.yaml
new file mode 100644
index 000000000..cb04a361d
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-gpt-5/tool_streaming.yaml
@@ -0,0 +1,125 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 512
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdzLjfDek4NLenFzdYH7xA7ZwhXR","object":"chat.completion.chunk","created":1760704607,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"call_HclHssdmN42q5djc4MO0fnIH","type":"function","function":{"name":"weather","arguments":""}}],"refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"wW0mB4WAi"}
+
+ data: {"id":"chatcmpl-CRdzLjfDek4NLenFzdYH7xA7ZwhXR","object":"chat.completion.chunk","created":1760704607,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"Djas7aoZyHzDdg5"}
+
+ data: {"id":"chatcmpl-CRdzLjfDek4NLenFzdYH7xA7ZwhXR","object":"chat.completion.chunk","created":1760704607,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"location"}}]},"finish_reason":null}],"usage":null,"obfuscation":"9OsYZ12UtG"}
+
+ data: {"id":"chatcmpl-CRdzLjfDek4NLenFzdYH7xA7ZwhXR","object":"chat.completion.chunk","created":1760704607,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"YIo7qOV9nxFX5"}
+
+ data: {"id":"chatcmpl-CRdzLjfDek4NLenFzdYH7xA7ZwhXR","object":"chat.completion.chunk","created":1760704607,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Flor"}}]},"finish_reason":null}],"usage":null,"obfuscation":"0t9tM3wGusJNdp"}
+
+ data: {"id":"chatcmpl-CRdzLjfDek4NLenFzdYH7xA7ZwhXR","object":"chat.completion.chunk","created":1760704607,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"ence"}}]},"finish_reason":null}],"usage":null,"obfuscation":"B5LwqW2HhJ6FQv"}
+
+ data: {"id":"chatcmpl-CRdzLjfDek4NLenFzdYH7xA7ZwhXR","object":"chat.completion.chunk","created":1760704607,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":","}}]},"finish_reason":null}],"usage":null,"obfuscation":"4"}
+
+ data: {"id":"chatcmpl-CRdzLjfDek4NLenFzdYH7xA7ZwhXR","object":"chat.completion.chunk","created":1760704607,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" Italy"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Bxlp9FKSsSrt"}
+
+ data: {"id":"chatcmpl-CRdzLjfDek4NLenFzdYH7xA7ZwhXR","object":"chat.completion.chunk","created":1760704607,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"}"}}]},"finish_reason":null}],"usage":null,"obfuscation":"zX7DDFi6nMXYRWx"}
+
+ data: {"id":"chatcmpl-CRdzLjfDek4NLenFzdYH7xA7ZwhXR","object":"chat.completion.chunk","created":1760704607,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"usage":null,"obfuscation":""}
+
+ data: {"id":"chatcmpl-CRdzLjfDek4NLenFzdYH7xA7ZwhXR","object":"chat.completion.chunk","created":1760704607,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":145,"completion_tokens":89,"total_tokens":234,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":64,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"9A0uIEuB"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 3.656144208s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 764
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_HclHssdmN42q5djc4MO0fnIH","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_HclHssdmN42q5djc4MO0fnIH","role":"tool"}],"model":"gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"Zo8VekTq7A"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"It"},"finish_reason":null}],"usage":null,"obfuscation":"0XPFHlQbT1"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"ās"},"finish_reason":null}],"usage":null,"obfuscation":"VqFEMOFD6V"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" currently"},"finish_reason":null}],"usage":null,"obfuscation":"05"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" about"},"finish_reason":null}],"usage":null,"obfuscation":"Hmjn6u"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" "},"finish_reason":null}],"usage":null,"obfuscation":"R6mJbjdENZ1"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"40"},"finish_reason":null}],"usage":null,"obfuscation":"aVWsABpE1B"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"°C"},"finish_reason":null}],"usage":null,"obfuscation":"vRN6vWf8xs"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" ("},"finish_reason":null}],"usage":null,"obfuscation":"qf1rIt73k5"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"104"},"finish_reason":null}],"usage":null,"obfuscation":"lkJ8qhLqA"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"°F"},"finish_reason":null}],"usage":null,"obfuscation":"x76W7W30bt"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":")"},"finish_reason":null}],"usage":null,"obfuscation":"X46lgG61m9r"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" in"},"finish_reason":null}],"usage":null,"obfuscation":"IXf4EbHLq"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Florence"},"finish_reason":null}],"usage":null,"obfuscation":"MQT"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":","},"finish_reason":null}],"usage":null,"obfuscation":"dxfY7jhGQdw"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Italy"},"finish_reason":null}],"usage":null,"obfuscation":"WKm2x1"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"finish_reason":null}],"usage":null,"obfuscation":"pCxaTBsDTC8"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":null,"obfuscation":"uEVTHt"}
+
+ data: {"id":"chatcmpl-CRdzPGEdWul8J6am5jOSgWZXVK6c8","object":"chat.completion.chunk","created":1760704611,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":176,"completion_tokens":217,"total_tokens":393,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":192,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"PJkBnc"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 4.725152125s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-o4-mini/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-o4-mini/simple.yaml
new file mode 100644
index 000000000..65c1131bf
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-o4-mini/simple.yaml
@@ -0,0 +1,68 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 168
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"o4-mini","max_completion_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdzlFzVyGYYxdsq9AKdmXfr7MukL",
+ "object": "chat.completion",
+ "created": 1760704633,
+ "model": "o4-mini-2025-04-16",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "OlĆ”!",
+ "refusal": null,
+ "annotations": []
+ },
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 19,
+ "completion_tokens": 84,
+ "total_tokens": 103,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 64,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": null
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.321425625s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-o4-mini/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-o4-mini/simple_streaming.yaml
new file mode 100644
index 000000000..de93f432a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-o4-mini/simple_streaming.yaml
@@ -0,0 +1,44 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 222
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"o4-mini","max_completion_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdznBTZHwiwBn3wgDxF7dJBJmoV8","object":"chat.completion.chunk","created":1760704635,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"In0BspKy"}
+
+ data: {"id":"chatcmpl-CRdznBTZHwiwBn3wgDxF7dJBJmoV8","object":"chat.completion.chunk","created":1760704635,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Oi"},"finish_reason":null}],"usage":null,"obfuscation":"RHZ9L7BA"}
+
+ data: {"id":"chatcmpl-CRdznBTZHwiwBn3wgDxF7dJBJmoV8","object":"chat.completion.chunk","created":1760704635,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"!"},"finish_reason":null}],"usage":null,"obfuscation":"X8LMBUcZV"}
+
+ data: {"id":"chatcmpl-CRdznBTZHwiwBn3wgDxF7dJBJmoV8","object":"chat.completion.chunk","created":1760704635,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":null,"obfuscation":"q1Yq"}
+
+ data: {"id":"chatcmpl-CRdznBTZHwiwBn3wgDxF7dJBJmoV8","object":"chat.completion.chunk","created":1760704635,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":19,"completion_tokens":148,"total_tokens":167,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":128,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"VkPeD"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 3.133094s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-o4-mini/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-o4-mini/tool.yaml
new file mode 100644
index 000000000..7f6538b21
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-o4-mini/tool.yaml
@@ -0,0 +1,143 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 460
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"o4-mini","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdzrg9Xy1ovxuEsdeaIh5HbAmzlq",
+ "object": "chat.completion",
+ "created": 1760704639,
+ "model": "o4-mini-2025-04-16",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": null,
+ "tool_calls": [
+ {
+ "id": "call_ZvgvJnyxcLxfnrw1vvy9QVMu",
+ "type": "function",
+ "function": {
+ "name": "weather",
+ "arguments": "{\"location\":\"Florence,Italy\"}"
+ }
+ }
+ ],
+ "refusal": null,
+ "annotations": []
+ },
+ "finish_reason": "tool_calls"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 64,
+ "completion_tokens": 89,
+ "total_tokens": 153,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 64,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": null
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.706478833s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 711
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_ZvgvJnyxcLxfnrw1vvy9QVMu","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_ZvgvJnyxcLxfnrw1vvy9QVMu","role":"tool"}],"model":"o4-mini","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CRdzu4C4EiqGRGJMYLhi1nnaygxRb",
+ "object": "chat.completion",
+ "created": 1760704642,
+ "model": "o4-mini-2025-04-16",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "The current temperature in Florence, Italy is 40°C. It's quite hot, so stay hydrated and try to stay in the shade or indoors with air conditioning if you can!",
+ "refusal": null,
+ "annotations": []
+ },
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 95,
+ "completion_tokens": 47,
+ "total_tokens": 142,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 0,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": null
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.575507083s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-o4-mini/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-o4-mini/tool_streaming.yaml
new file mode 100644
index 000000000..5b2f388bc
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICommon/openai-o4-mini/tool_streaming.yaml
@@ -0,0 +1,149 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 514
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"o4-mini","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdzvzjPGfHTfxYWBuHOE6Fqgbd3w","object":"chat.completion.chunk","created":1760704643,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"call_XevDuUMYIPg4YiA0oGOYlJTt","type":"function","function":{"name":"weather","arguments":""}}],"refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"kPmohDP"}
+
+ data: {"id":"chatcmpl-CRdzvzjPGfHTfxYWBuHOE6Fqgbd3w","object":"chat.completion.chunk","created":1760704643,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"l8ZBA4sqknndZ"}
+
+ data: {"id":"chatcmpl-CRdzvzjPGfHTfxYWBuHOE6Fqgbd3w","object":"chat.completion.chunk","created":1760704643,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"location"}}]},"finish_reason":null}],"usage":null,"obfuscation":"uDtteUEc"}
+
+ data: {"id":"chatcmpl-CRdzvzjPGfHTfxYWBuHOE6Fqgbd3w","object":"chat.completion.chunk","created":1760704643,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"RLch0C57YvN"}
+
+ data: {"id":"chatcmpl-CRdzvzjPGfHTfxYWBuHOE6Fqgbd3w","object":"chat.completion.chunk","created":1760704643,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Flor"}}]},"finish_reason":null}],"usage":null,"obfuscation":"ubrkTTBECEch"}
+
+ data: {"id":"chatcmpl-CRdzvzjPGfHTfxYWBuHOE6Fqgbd3w","object":"chat.completion.chunk","created":1760704643,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"ence"}}]},"finish_reason":null}],"usage":null,"obfuscation":"ymKoTibZF2Wx"}
+
+ data: {"id":"chatcmpl-CRdzvzjPGfHTfxYWBuHOE6Fqgbd3w","object":"chat.completion.chunk","created":1760704643,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":","}}]},"finish_reason":null}],"usage":null,"obfuscation":"lunIUN6UnqixGVS"}
+
+ data: {"id":"chatcmpl-CRdzvzjPGfHTfxYWBuHOE6Fqgbd3w","object":"chat.completion.chunk","created":1760704643,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" Italy"}}]},"finish_reason":null}],"usage":null,"obfuscation":"0R7CM90wrz"}
+
+ data: {"id":"chatcmpl-CRdzvzjPGfHTfxYWBuHOE6Fqgbd3w","object":"chat.completion.chunk","created":1760704643,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"}"}}]},"finish_reason":null}],"usage":null,"obfuscation":"UoUH2orSC5M6H"}
+
+ data: {"id":"chatcmpl-CRdzvzjPGfHTfxYWBuHOE6Fqgbd3w","object":"chat.completion.chunk","created":1760704643,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"usage":null,"obfuscation":"kyr6C4vgS6KpIx"}
+
+ data: {"id":"chatcmpl-CRdzvzjPGfHTfxYWBuHOE6Fqgbd3w","object":"chat.completion.chunk","created":1760704643,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":64,"completion_tokens":25,"total_tokens":89,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"BMYaOAORX"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 1.742662959s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 766
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_XevDuUMYIPg4YiA0oGOYlJTt","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_XevDuUMYIPg4YiA0oGOYlJTt","role":"tool"}],"model":"o4-mini","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"J9fqcxQ0"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"The"},"finish_reason":null}],"usage":null,"obfuscation":"9psTh4S"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" current"},"finish_reason":null}],"usage":null,"obfuscation":"qC"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" temperature"},"finish_reason":null}],"usage":null,"obfuscation":"IWaJutlGMgxvCa"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" in"},"finish_reason":null}],"usage":null,"obfuscation":"7GnoJrO"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Florence"},"finish_reason":null}],"usage":null,"obfuscation":"C"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":","},"finish_reason":null}],"usage":null,"obfuscation":"7uviSp1f4"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Italy"},"finish_reason":null}],"usage":null,"obfuscation":"OIuc"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"finish_reason":null}],"usage":null,"obfuscation":"FefXEvV"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" "},"finish_reason":null}],"usage":null,"obfuscation":"zMQLb8hcU"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"40"},"finish_reason":null}],"usage":null,"obfuscation":"dqTN5maD"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"°C"},"finish_reason":null}],"usage":null,"obfuscation":"zmWzszVf"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"finish_reason":null}],"usage":null,"obfuscation":"wcGkYYod2"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Would"},"finish_reason":null}],"usage":null,"obfuscation":"Y3wl"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" you"},"finish_reason":null}],"usage":null,"obfuscation":"whFvbn"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" like"},"finish_reason":null}],"usage":null,"obfuscation":"zleYy"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" more"},"finish_reason":null}],"usage":null,"obfuscation":"LvKVS"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" details"},"finish_reason":null}],"usage":null,"obfuscation":"6S"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" ("},"finish_reason":null}],"usage":null,"obfuscation":"CN2vr0cw"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"e"},"finish_reason":null}],"usage":null,"obfuscation":"MnqKVTshP"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".g"},"finish_reason":null}],"usage":null,"obfuscation":"3dgCtAmi"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".,"},"finish_reason":null}],"usage":null,"obfuscation":"3PssNymm"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" humidity"},"finish_reason":null}],"usage":null,"obfuscation":"2"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":","},"finish_reason":null}],"usage":null,"obfuscation":"YOzesgDGD"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" wind"},"finish_reason":null}],"usage":null,"obfuscation":"WcWEd"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" speed"},"finish_reason":null}],"usage":null,"obfuscation":"22yU"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":","},"finish_reason":null}],"usage":null,"obfuscation":"YM4evRNHw"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" forecast"},"finish_reason":null}],"usage":null,"obfuscation":"X"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":")?"},"finish_reason":null}],"usage":null,"obfuscation":"kWnwQGZK"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":null,"obfuscation":"u1V5"}
+
+ data: {"id":"chatcmpl-CRdzxUM84mYwaVLVUEQ0BMkH7N3rK","object":"chat.completion.chunk","created":1760704645,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":95,"completion_tokens":40,"total_tokens":135,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"WOSHdxIx"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 905.154333ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-4-fast/complex_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-4-fast/complex_object.yaml
new file mode 100644
index 000000000..4f3591500
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-4-fast/complex_object.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 962
+ host: ""
+ body: '{"messages":[{"content":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","role":"user"}],"model":"grok-4-fast","max_tokens":4000,"tool_choice":{"function":{"name":"Book"},"type":"function"},"tools":[{"function":{"name":"Book","strict":false,"description":"A book with title, author, genres, and publication year","parameters":{"properties":{"author":{"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"c507c7e0-9670-a02e-8c70-1df65c243406","object":"chat.completion","created":1762637614,"model":"grok-4-fast-reasoning","choices":[{"index":0,"message":{"role":"assistant","content":"","tool_calls":[{"id":"call_93127190","function":{"name":"Book","arguments":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"fantasy\",\"adventure\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"},"type":"function"}],"refusal":null},"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":468,"completion_tokens":83,"total_tokens":1122,"prompt_tokens_details":{"text_tokens":468,"audio_tokens":0,"image_tokens":0,"cached_tokens":305},"completion_tokens_details":{"reasoning_tokens":571,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_bfbe7bd0a2"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.442305458s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-4-fast/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-4-fast/complex_object_streaming.yaml
new file mode 100644
index 000000000..93d28c0b0
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-4-fast/complex_object_streaming.yaml
@@ -0,0 +1,1158 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1016
+ host: ""
+ body: '{"messages":[{"content":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","role":"user"}],"model":"grok-4-fast","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":{"function":{"name":"Book"},"type":"function"},"tools":[{"function":{"name":"Book","strict":false,"description":"A book with title, author, genres, and publication year","parameters":{"properties":{"author":{"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"role":"assistant"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637618,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637619,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637620,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637621,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_96704413","function":{"name":"Book","arguments":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"fantasy\",\"adventure\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"},"index":0,"type":"function"}]}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637621,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"7737a2b5-8585-c605-a8bb-3007b764dbfa","object":"chat.completion.chunk","created":1762637621,"model":"grok-4-fast-reasoning","choices":[],"usage":{"prompt_tokens":468,"completion_tokens":79,"total_tokens":1106,"prompt_tokens_details":{"text_tokens":468,"audio_tokens":0,"image_tokens":0,"cached_tokens":305},"completion_tokens_details":{"reasoning_tokens":559,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 168.769958ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-4-fast/simple_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-4-fast/simple_object.yaml
new file mode 100644
index 000000000..7e8648974
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-4-fast/simple_object.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 626
+ host: ""
+ body: '{"messages":[{"content":"Generate information about a person named Alice who is 30 years old and lives in Paris.","role":"user"}],"model":"grok-4-fast","max_tokens":4000,"tool_choice":{"function":{"name":"Person"},"type":"function"},"tools":[{"function":{"name":"Person","strict":false,"description":"A person with name, age, and city","parameters":{"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"c741f0c0-b3ad-605e-94e9-aa17f8ad0f1f","object":"chat.completion","created":1762637610,"model":"grok-4-fast-reasoning","choices":[{"index":0,"message":{"role":"assistant","content":"","tool_calls":[{"id":"call_85975414","function":{"name":"Person","arguments":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"},"type":"function"}],"refusal":null},"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":401,"completion_tokens":46,"total_tokens":787,"prompt_tokens_details":{"text_tokens":401,"audio_tokens":0,"image_tokens":0,"cached_tokens":305},"completion_tokens_details":{"reasoning_tokens":340,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_bfbe7bd0a2"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.228575458s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-4-fast/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-4-fast/simple_object_streaming.yaml
new file mode 100644
index 000000000..80ef0a183
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-4-fast/simple_object_streaming.yaml
@@ -0,0 +1,378 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 680
+ host: ""
+ body: '{"messages":[{"content":"Generate information about a person named Alice who is 30 years old and lives in Paris.","role":"user"}],"model":"grok-4-fast","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":{"function":{"name":"Person"},"type":"function"},"tools":[{"function":{"name":"Person","strict":false,"description":"A person with name, age, and city","parameters":{"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"role":"assistant"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637613,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637614,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_85608889","function":{"name":"Person","arguments":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"},"index":0,"type":"function"}]}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637614,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"a6a4a8e9-1f95-504d-3f2c-0f106447d2d2","object":"chat.completion.chunk","created":1762637614,"model":"grok-4-fast-reasoning","choices":[],"usage":{"prompt_tokens":401,"completion_tokens":46,"total_tokens":616,"prompt_tokens_details":{"text_tokens":401,"audio_tokens":0,"image_tokens":0,"cached_tokens":400},"completion_tokens_details":{"reasoning_tokens":169,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 176.963166ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-code-fast/complex_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-code-fast/complex_object.yaml
new file mode 100644
index 000000000..361b9a00e
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-code-fast/complex_object.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 967
+ host: ""
+ body: '{"messages":[{"content":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","role":"user"}],"model":"grok-code-fast-1","max_tokens":4000,"tool_choice":{"function":{"name":"Book"},"type":"function"},"tools":[{"function":{"name":"Book","strict":false,"description":"A book with title, author, genres, and publication year","parameters":{"properties":{"author":{"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"2537f822-595e-1e8e-fe59-59c9761c15a1","object":"chat.completion","created":1762637624,"model":"grok-code-fast-1","choices":[{"index":0,"message":{"role":"assistant","content":"","tool_calls":[{"id":"call_05092142","function":{"name":"Book","arguments":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"fantasy\",\"adventure\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"},"type":"function"}],"refusal":null},"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":496,"completion_tokens":81,"total_tokens":820,"prompt_tokens_details":{"text_tokens":496,"audio_tokens":0,"image_tokens":0,"cached_tokens":320},"completion_tokens_details":{"reasoning_tokens":243,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_10f00c862d"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.213765834s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-code-fast/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-code-fast/complex_object_streaming.yaml
new file mode 100644
index 000000000..ac074e4c2
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-code-fast/complex_object_streaming.yaml
@@ -0,0 +1,320 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1021
+ host: ""
+ body: '{"messages":[{"content":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","role":"user"}],"model":"grok-code-fast-1","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":{"function":{"name":"Book"},"type":"function"},"tools":[{"function":{"name":"Book","strict":false,"description":"A book with title, author, genres, and publication year","parameters":{"properties":{"author":{"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"The","role":"assistant"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" user"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" asked"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" to"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" generate"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" information"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" about"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" '"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"The"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" Lord"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" of"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" Rings"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"'"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" by"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" J"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":".R"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":".R"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"."}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" Tolkien"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" with"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" genres"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" fantasy"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" and"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" adventure"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" and"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" publication"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" year"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" "}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"195"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"4"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":".\n"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637626,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_07349906","function":{"name":"Book","arguments":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"fantasy\",\"adventure\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"},"index":0,"type":"function"}]}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"821dc033-d41a-abe2-4f7a-61da882f43b8","object":"chat.completion.chunk","created":1762637627,"model":"grok-code-fast-1","choices":[],"usage":{"prompt_tokens":496,"completion_tokens":77,"total_tokens":713,"prompt_tokens_details":{"text_tokens":496,"audio_tokens":0,"image_tokens":0,"cached_tokens":448},"completion_tokens_details":{"reasoning_tokens":140,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_10f00c862d"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 391.881125ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-code-fast/simple_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-code-fast/simple_object.yaml
new file mode 100644
index 000000000..1520ab859
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-code-fast/simple_object.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 631
+ host: ""
+ body: '{"messages":[{"content":"Generate information about a person named Alice who is 30 years old and lives in Paris.","role":"user"}],"model":"grok-code-fast-1","max_tokens":4000,"tool_choice":{"function":{"name":"Person"},"type":"function"},"tools":[{"function":{"name":"Person","strict":false,"description":"A person with name, age, and city","parameters":{"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"8d3d6258-cbe1-f871-55c0-32bd3487f2d7","object":"chat.completion","created":1762637621,"model":"grok-code-fast-1","choices":[{"index":0,"message":{"role":"assistant","content":"","tool_calls":[{"id":"call_38033184","function":{"name":"Person","arguments":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"},"type":"function"}],"refusal":null},"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":429,"completion_tokens":44,"total_tokens":630,"prompt_tokens_details":{"text_tokens":429,"audio_tokens":0,"image_tokens":0,"cached_tokens":320},"completion_tokens_details":{"reasoning_tokens":157,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_10f00c862d"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.615676541s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-code-fast/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-code-fast/simple_object_streaming.yaml
new file mode 100644
index 000000000..4ac468289
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/xai-grok-code-fast/simple_object_streaming.yaml
@@ -0,0 +1,338 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 685
+ host: ""
+ body: '{"messages":[{"content":"Generate information about a person named Alice who is 30 years old and lives in Paris.","role":"user"}],"model":"grok-code-fast-1","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":{"function":{"name":"Person"},"type":"function"},"tools":[{"function":{"name":"Person","strict":false,"description":"A person with name, age, and city","parameters":{"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"The","role":"assistant"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" user"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" asked"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" to"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" generate"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" information"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" about"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" a"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" person"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" named"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" Alice"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" "}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"30"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" years"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" old"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" living"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" in"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" Paris"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"."}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" There's"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" a"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" tool"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" called"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"Person"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"\""}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" that"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" matches"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" this"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" exactly"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":":"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" it"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" has"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" name"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" age"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" and"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" city"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":".\n"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_71440968","function":{"name":"Person","arguments":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"},"index":0,"type":"function"}]}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"\n\n## Investigating user request \n- The user asked for information about Alice, a 30-year-old living in Paris."},"finish_reason":"tool_calls"}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"8887124f-28ef-3f97-76c9-b348294a5bd5","object":"chat.completion.chunk","created":1762637623,"model":"grok-code-fast-1","choices":[],"usage":{"prompt_tokens":429,"completion_tokens":44,"total_tokens":622,"prompt_tokens_details":{"text_tokens":429,"audio_tokens":0,"image_tokens":0,"cached_tokens":384},"completion_tokens_details":{"reasoning_tokens":149,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_10f00c862d"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 244.686625ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/zai-glm-4.5/complex_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/zai-glm-4.5/complex_object.yaml
new file mode 100644
index 000000000..62a93ca21
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/zai-glm-4.5/complex_object.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 958
+ host: ""
+ body: '{"messages":[{"content":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","role":"user"}],"model":"glm-4.5","max_tokens":4000,"tool_choice":{"function":{"name":"Book"},"type":"function"},"tools":[{"function":{"name":"Book","strict":false,"description":"A book with title, author, genres, and publication year","parameters":{"properties":{"author":{"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"choices":[{"finish_reason":"tool_calls","index":0,"message":{"content":"","reasoning_content":"\nThe user is asking me to generate information about \"The Lord of the Rings\" book. They''ve provided specific details:\n- Title: \"The Lord of the Rings\"\n- Author: J.R.R. Tolkien \n- Genres: fantasy and adventure\n- Publication year: 1954\n\nI need to use the Book function to create this information. Let me check the required parameters:\n- title: \"The Lord of the Rings\" ā\n- author: This needs to be an object with name and nationality. The user provided \"J.R.R. Tolkien\" as the name, but didn''t specify nationality. However, I know Tolkien was British, so I should include that.\n- genres: [\"fantasy\", \"adventure\"] ā\n- published_year: 1954 ā\n\nFor the author parameter, I need to create an object with:\n- name: \"J.R.R. Tolkien\"\n- nationality: I should use \"British\" as Tolkien was from the UK\n\nLet me make the function call.","role":"assistant","tool_calls":[{"function":{"arguments":"{\"author\":{\"name\": \"J.R.R. Tolkien\", \"nationality\": \"British\"},\"genres\":[\"fantasy\", \"adventure\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}","name":"Book"},"id":"call_-8178161609897772812","index":0,"type":"function"}]}}],"created":1762637648,"id":"20251109053400036d2d4153bd41bf","model":"glm-4.5","request_id":"20251109053400036d2d4153bd41bf","usage":{"completion_tokens":275,"prompt_tokens":317,"prompt_tokens_details":{"cached_tokens":43},"total_tokens":592}}'
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 8.903275792s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/zai-glm-4.5/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/zai-glm-4.5/complex_object_streaming.yaml
new file mode 100644
index 000000000..5f73fae91
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/zai-glm-4.5/complex_object_streaming.yaml
@@ -0,0 +1,446 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1012
+ host: ""
+ body: '{"messages":[{"content":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","role":"user"}],"model":"glm-4.5","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":{"function":{"name":"Book"},"type":"function"},"tools":[{"function":{"name":"Book","strict":false,"description":"A book with title, author, genres, and publication year","parameters":{"properties":{"author":{"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"The"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" user"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" wants"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" me"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" to"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" generate"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" information"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" about"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"The"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Lord"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" of"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Rings"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\""}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" book"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" by"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" J"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":".R"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":".R"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Tolkien"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" They"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"'ve"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" provided"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" specific"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" details"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":\n"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Title"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"The"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Lord"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" of"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Rings"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\"\n"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Author"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" J"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":".R"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":".R"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Tolkien"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Gen"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"res"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" fantasy"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" and"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" adventure"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Publication"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" year"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"195"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"4"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n\n"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"I"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" need"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" to"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" use"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Book"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" function"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" to"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" create"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" this"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" information"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Let"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" me"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" check"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" required"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" parameters"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":\n"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" title"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"The"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Lord"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" of"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Rings"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\""}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" ā"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" author"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" This"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" needs"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" to"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" be"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" an"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" object"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" with"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" name"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" and"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" nationality"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" The"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" user"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" provided"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"J"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":".R"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":".R"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Tolkien"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\""}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" as"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" name"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":","}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" but"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" didn"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"'t"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" specify"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" nationality"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" I"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" should"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" use"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" a"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" reasonable"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" nationality"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" for"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Tolkien"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" -"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" he"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" was"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" British"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"/"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"English"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":".\n"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" genres"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" [\""}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"fant"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"asy"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\","}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"ad"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"venture"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\"]"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" ā"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" published"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"_year"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"195"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"4"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" ā"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n\n"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"For"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" author"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":","}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" I"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" need"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" to"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" create"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" an"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" object"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" with"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" name"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"J"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":".R"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":".R"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Tolkien"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\""}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" and"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" nationality"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Tolkien"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" was"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" British"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":","}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" so"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" I"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"'ll"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" use"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"British"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\""}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" as"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" nationality"}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_94b356a0eb5f46da8edc2ac4","index":0,"type":"function","function":{"name":"Book","arguments":"{\"author\":{\"name\": \"J.R.R. Tolkien\", \"nationality\": \"British\"},\"genres\":[\"fantasy\", \"adventure\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"}}]}}]}
+
+ data: {"id":"202511090534097e2c534f7c00470a","created":1762637649,"model":"glm-4.5","choices":[{"index":0,"finish_reason":"tool_calls","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":317,"completion_tokens":272,"total_tokens":589,"prompt_tokens_details":{"cached_tokens":316}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream;charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 650.778291ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/zai-glm-4.5/simple_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/zai-glm-4.5/simple_object.yaml
new file mode 100644
index 000000000..2cb27dfed
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/zai-glm-4.5/simple_object.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 622
+ host: ""
+ body: '{"messages":[{"content":"Generate information about a person named Alice who is 30 years old and lives in Paris.","role":"user"}],"model":"glm-4.5","max_tokens":4000,"tool_choice":{"function":{"name":"Person"},"type":"function"},"tools":[{"function":{"name":"Person","strict":false,"description":"A person with name, age, and city","parameters":{"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"choices":[{"finish_reason":"tool_calls","index":0,"message":{"content":"","reasoning_content":"\nThe user is asking me to generate information about a person named Alice who is 30 years old and lives in Paris. Looking at the available function, I have a \"Person\" function that takes three required parameters:\n- name: \"Alice\" \n- age: 30\n- city: \"Paris\"\n\nAll the required parameters are provided, so I can call this function.","role":"assistant","tool_calls":[{"function":{"arguments":"{\"age\": 30, \"city\": \"Paris\", \"name\": \"Alice\"}","name":"Person"},"id":"call_-8178200539482324764","index":0,"type":"function"}]}}],"created":1762637635,"id":"2025110905335254041e69de3b448e","model":"glm-4.5","request_id":"2025110905335254041e69de3b448e","usage":{"completion_tokens":121,"prompt_tokens":230,"prompt_tokens_details":{"cached_tokens":43},"total_tokens":351}}'
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 6.174196125s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/zai-glm-4.5/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/zai-glm-4.5/simple_object_streaming.yaml
new file mode 100644
index 000000000..8e6668ce2
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatObjectGeneration/zai-glm-4.5/simple_object_streaming.yaml
@@ -0,0 +1,200 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 676
+ host: ""
+ body: '{"messages":[{"content":"Generate information about a person named Alice who is 30 years old and lives in Paris.","role":"user"}],"model":"glm-4.5","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":{"function":{"name":"Person"},"type":"function"},"tools":[{"function":{"name":"Person","strict":false,"description":"A person with name, age, and city","parameters":{"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"The"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" user"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" wants"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" me"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" to"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" generate"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" information"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" about"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" a"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" person"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" with"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" specific"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" details"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":\n"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Name"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Alice"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Age"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"30"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" City"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Paris"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n\n"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"I"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" have"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" a"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Person"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" function"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" available"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" that"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" takes"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" these"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" exact"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" parameters"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":\n"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" name"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" ("}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"required"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"):"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"Alice"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\"\n"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" age"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" ("}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"required"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"):"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"30"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" city"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" ("}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"required"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"):"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"Paris"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\"\n\n"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"All"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" required"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" parameters"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" are"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" provided"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":","}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" so"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" I"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" can"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" make"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" function"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" call"}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_11f61396a06b43ebb9ab7992","index":0,"type":"function","function":{"name":"Person","arguments":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"}}]}}]}
+
+ data: {"id":"2025110905335643ffc6855fee49b2","created":1762637636,"model":"glm-4.5","choices":[{"index":0,"finish_reason":"tool_calls","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":230,"completion_tokens":112,"total_tokens":342,"prompt_tokens_details":{"cached_tokens":43}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream;charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.864133208s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/multi_tool.yaml
new file mode 100644
index 000000000..5b98ddddb
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/multi_tool.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 837
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"moonshotai/kimi-k2-instruct-0905","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.groq.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {"id":"chatcmpl-f99f9572-5553-418a-a974-3ce7763f287d","object":"chat.completion","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","choices":[{"index":0,"message":{"role":"assistant","content":"I'll add and multiply the numbers 2 and 3 for you.","tool_calls":[{"id":"functions.add:0","type":"function","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"}},{"id":"functions.multiply:1","type":"function","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"}}]},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"queue_time":0.16105511,"prompt_tokens":205,"prompt_time":0.021381762,"completion_tokens":55,"completion_time":0.177128832,"total_tokens":260,"total_time":0.198510594},"usage_breakdown":null,"system_fingerprint":"fp_5fe129dff6","x_groq":{"id":"req_01k9s5gdn9fqpaz58zxaarqt7b"},"service_tier":"on_demand"}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 410.276791ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1279
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"I''ll add and multiply the numbers 2 and 3 for you.","tool_calls":[{"id":"functions.add:0","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"functions.multiply:1","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"functions.add:0","role":"tool"},{"content":"6","tool_call_id":"functions.multiply:1","role":"tool"}],"model":"moonshotai/kimi-k2-instruct-0905","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.groq.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {"id":"chatcmpl-21bda724-6180-4357-943e-a555622dd5b9","object":"chat.completion","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","choices":[{"index":0,"message":{"role":"assistant","content":"The results are:\n- Addition: 2 + 3 = 5\n- Multiplication: 2 Ć 3 = 6"},"logprobs":null,"finish_reason":"stop"}],"usage":{"queue_time":0.162310812,"prompt_tokens":297,"prompt_time":0.029482976,"completion_tokens":29,"completion_time":0.06281568,"total_tokens":326,"total_time":0.092298656},"usage_breakdown":null,"system_fingerprint":"fp_3312304636","x_groq":{"id":"req_01k9s5ge24ehwsanxan8an35he"},"service_tier":"on_demand"}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 305.567541ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/multi_tool_streaming.yaml
new file mode 100644
index 000000000..b46e603a5
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/multi_tool_streaming.yaml
@@ -0,0 +1,173 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 874
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"moonshotai/kimi-k2-instruct-0905","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.groq.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}],"x_groq":{"id":"req_01k9s5gebzfqpr76b0dcepxd89"}}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":"I'll"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" calculate"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" both"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" sum"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" product"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":"2"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"tool_calls":[{"id":"functions.add:0","type":"function","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"},"index":0}]},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"tool_calls":[{"id":"functions.multiply:1","type":"function","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"},"index":1}]},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"x_groq":{"id":"req_01k9s5gebzfqpr76b0dcepxd89","usage":{"queue_time":0.162914893,"prompt_tokens":201,"prompt_time":0.052741139,"completion_tokens":57,"completion_time":0.195291661,"total_tokens":258,"total_time":0.2480328}},"usage":{"queue_time":0.162914893,"prompt_tokens":201,"prompt_time":0.052741139,"completion_tokens":57,"completion_time":0.195291661,"total_tokens":258,"total_time":0.2480328}}
+
+ data: {"id":"chatcmpl-2c900147-daa3-4ba7-9f06-34cddb9750d2","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[],"usage":{"queue_time":0.162914893,"prompt_tokens":201,"prompt_time":0.052741139,"completion_tokens":57,"completion_time":0.195291661,"total_tokens":258,"total_time":0.2480328},"service_tier":"on_demand"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 270.783709ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1325
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"I''ll calculate both the sum and product of 2 and 3 for you.","tool_calls":[{"id":"functions.add:0","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"functions.multiply:1","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"functions.add:0","role":"tool"},{"content":"6","tool_call_id":"functions.multiply:1","role":"tool"}],"model":"moonshotai/kimi-k2-instruct-0905","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.groq.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}],"x_groq":{"id":"req_01k9s5geteehya7n9jqe65paze"}}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":" results"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":" are"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":":\n"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":" **"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"Addition"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"**:"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"2"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":" +"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":" ="},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"5"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":" **"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"Multi"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"plication"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"**:"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"2"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":" Ć"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":" ="},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"6"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"x_groq":{"id":"req_01k9s5geteehya7n9jqe65paze","usage":{"queue_time":0.16011279,"prompt_tokens":295,"prompt_time":0.054205662,"completion_tokens":31,"completion_time":0.082124494,"total_tokens":326,"total_time":0.136330156}},"usage":{"queue_time":0.16011279,"prompt_tokens":295,"prompt_time":0.054205662,"completion_tokens":31,"completion_time":0.082124494,"total_tokens":326,"total_time":0.136330156}}
+
+ data: {"id":"chatcmpl-76e3527c-b479-46a6-982f-fe721501bb7a","object":"chat.completion.chunk","created":1762854976,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[],"usage":{"queue_time":0.16011279,"prompt_tokens":295,"prompt_time":0.054205662,"completion_tokens":31,"completion_time":0.082124494,"total_tokens":326,"total_time":0.136330156},"service_tier":"on_demand"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 265.328458ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/simple.yaml
new file mode 100644
index 000000000..deabd88b4
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/simple.yaml
@@ -0,0 +1,34 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 182
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"moonshotai/kimi-k2-instruct-0905","max_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.groq.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {"id":"chatcmpl-9d25476d-ffb3-4fc0-8a33-6e84b5ede19c","object":"chat.completion","created":1762854973,"model":"moonshotai/kimi-k2-instruct-0905","choices":[{"index":0,"message":{"role":"assistant","content":"OlĆ”!"},"logprobs":null,"finish_reason":"stop"}],"usage":{"queue_time":0.161356542,"prompt_tokens":20,"prompt_time":0.009083588,"completion_tokens":4,"completion_time":0.008812502,"total_tokens":24,"total_time":0.01789609},"usage_breakdown":null,"system_fingerprint":"fp_5fe129dff6","x_groq":{"id":"req_01k9s5gc22f6m968npajvjx0x0"},"service_tier":"on_demand"}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 374.755334ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/simple_streaming.yaml
new file mode 100644
index 000000000..a79fe0d2c
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/simple_streaming.yaml
@@ -0,0 +1,46 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 236
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"moonshotai/kimi-k2-instruct-0905","max_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.groq.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-01c5e4bc-e533-4f23-bc74-32b9f2f473b0","object":"chat.completion.chunk","created":1762854973,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}],"x_groq":{"id":"req_01k9s5gc9mfqk9exgvmtm3gw25"}}
+
+ data: {"id":"chatcmpl-01c5e4bc-e533-4f23-bc74-32b9f2f473b0","object":"chat.completion.chunk","created":1762854973,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"Ol"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-01c5e4bc-e533-4f23-bc74-32b9f2f473b0","object":"chat.completion.chunk","created":1762854973,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"Ć”"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-01c5e4bc-e533-4f23-bc74-32b9f2f473b0","object":"chat.completion.chunk","created":1762854973,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{"content":"!"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-01c5e4bc-e533-4f23-bc74-32b9f2f473b0","object":"chat.completion.chunk","created":1762854973,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"x_groq":{"id":"req_01k9s5gc9mfqk9exgvmtm3gw25","usage":{"queue_time":0.160975287,"prompt_tokens":20,"prompt_time":0.009101728,"completion_tokens":4,"completion_time":0.009250085,"total_tokens":24,"total_time":0.018351813}},"usage":{"queue_time":0.160975287,"prompt_tokens":20,"prompt_time":0.009101728,"completion_tokens":4,"completion_time":0.009250085,"total_tokens":24,"total_time":0.018351813}}
+
+ data: {"id":"chatcmpl-01c5e4bc-e533-4f23-bc74-32b9f2f473b0","object":"chat.completion.chunk","created":1762854973,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_5fe129dff6","choices":[],"usage":{"queue_time":0.160975287,"prompt_tokens":20,"prompt_time":0.009101728,"completion_tokens":4,"completion_time":0.009250085,"total_tokens":24,"total_time":0.018351813},"service_tier":"on_demand"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 221.770167ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/tool.yaml
new file mode 100644
index 000000000..53c795371
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/tool.yaml
@@ -0,0 +1,65 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 474
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"moonshotai/kimi-k2-instruct-0905","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.groq.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {"id":"chatcmpl-7822ddc7-c616-45cc-9315-1da4ae05d870","object":"chat.completion","created":1762854974,"model":"moonshotai/kimi-k2-instruct-0905","choices":[{"index":0,"message":{"role":"assistant","tool_calls":[{"id":"functions.weather:0","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence,Italy\"}"}}]},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"queue_time":0.162552698,"prompt_tokens":93,"prompt_time":0.01385344,"completion_tokens":21,"completion_time":0.067437002,"total_tokens":114,"total_time":0.081290442},"usage_breakdown":null,"system_fingerprint":"fp_3312304636","x_groq":{"id":"req_01k9s5gcgyf6ttekbzf8v4fta8"},"service_tier":"on_demand"}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 294.483708ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 705
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"functions.weather:0","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"functions.weather:0","role":"tool"}],"model":"moonshotai/kimi-k2-instruct-0905","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.groq.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {"id":"chatcmpl-97e734c9-073a-48bf-926d-462e1eb23a77","object":"chat.completion","created":1762854974,"model":"moonshotai/kimi-k2-instruct-0905","choices":[{"index":0,"message":{"role":"assistant","content":"It's currently 40°C in Florence, Italy."},"logprobs":null,"finish_reason":"stop"}],"usage":{"queue_time":0.162461202,"prompt_tokens":132,"prompt_time":0.017534991,"completion_tokens":11,"completion_time":0.021573995,"total_tokens":143,"total_time":0.039108986},"usage_breakdown":null,"system_fingerprint":"fp_3312304636","x_groq":{"id":"req_01k9s5gct2fqm9ew59aphgfzdc"},"service_tier":"on_demand"}
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 248.764041ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/tool_streaming.yaml
new file mode 100644
index 000000000..6af65686a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/groq-kimi-k2/tool_streaming.yaml
@@ -0,0 +1,111 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 528
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"moonshotai/kimi-k2-instruct-0905","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.groq.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-6059e0d5-a7a8-4b9b-9d23-8b44a9175a59","object":"chat.completion.chunk","created":1762854974,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}],"x_groq":{"id":"req_01k9s5gd20ehs83d8fkh52fr85"}}
+
+ data: {"id":"chatcmpl-6059e0d5-a7a8-4b9b-9d23-8b44a9175a59","object":"chat.completion.chunk","created":1762854974,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"tool_calls":[{"id":"functions.weather:0","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence,Italy\"}"},"index":0}]},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-6059e0d5-a7a8-4b9b-9d23-8b44a9175a59","object":"chat.completion.chunk","created":1762854974,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"x_groq":{"id":"req_01k9s5gd20ehs83d8fkh52fr85","usage":{"queue_time":0.162791944,"prompt_tokens":93,"prompt_time":0.014461869,"completion_tokens":21,"completion_time":0.067222006,"total_tokens":114,"total_time":0.081683875}},"usage":{"queue_time":0.162791944,"prompt_tokens":93,"prompt_time":0.014461869,"completion_tokens":21,"completion_time":0.067222006,"total_tokens":114,"total_time":0.081683875}}
+
+ data: {"id":"chatcmpl-6059e0d5-a7a8-4b9b-9d23-8b44a9175a59","object":"chat.completion.chunk","created":1762854974,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[],"usage":{"queue_time":0.162791944,"prompt_tokens":93,"prompt_time":0.014461869,"completion_tokens":21,"completion_time":0.067222006,"total_tokens":114,"total_time":0.081683875},"service_tier":"on_demand"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 289.580708ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 759
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"functions.weather:0","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"functions.weather:0","role":"tool"}],"model":"moonshotai/kimi-k2-instruct-0905","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.groq.com/openai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}],"x_groq":{"id":"req_01k9s5gdbweht9vbmhq6m82xx5"}}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":"Fl"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":"ore"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":"nce"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" Italy"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" currently"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" experiencing"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" very"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" hot"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" at"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":"40"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":"°C"},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"x_groq":{"id":"req_01k9s5gdbweht9vbmhq6m82xx5","usage":{"queue_time":0.162467912,"prompt_tokens":132,"prompt_time":0.020355587,"completion_tokens":17,"completion_time":0.063136224,"total_tokens":149,"total_time":0.083491811}},"usage":{"queue_time":0.162467912,"prompt_tokens":132,"prompt_time":0.020355587,"completion_tokens":17,"completion_time":0.063136224,"total_tokens":149,"total_time":0.083491811}}
+
+ data: {"id":"chatcmpl-e14af5f2-dcb6-4bfb-9fce-dbe848e76368","object":"chat.completion.chunk","created":1762854975,"model":"moonshotai/kimi-k2-instruct-0905","system_fingerprint":"fp_3312304636","choices":[],"usage":{"queue_time":0.162467912,"prompt_tokens":132,"prompt_time":0.020355587,"completion_tokens":17,"completion_time":0.063136224,"total_tokens":149,"total_time":0.083491811},"service_tier":"on_demand"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 251.184375ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/multi_tool.yaml
new file mode 100644
index 000000000..75d4faff6
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/multi_tool.yaml
@@ -0,0 +1,61 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 829
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"zai-org/GLM-4.6:cerebras","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://router.huggingface.co/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: '{"id":"chatcmpl-7189d22c-3447-47bd-99e5-5e5b509d6373","choices":[{"finish_reason":"tool_calls","index":0,"message":{"content":"\nI''ll add and multiply the numbers 2 and 3 for you.\n","reasoning":"The user wants me to add and multiply the numbers 2 and 3. Looking at the available functions, I have:\n1. add function - to add two numbers\n2. multiply function - to multiply two numbers\n\nI need to call both functions as instructed. Let me call both functions with a=2 and b=3.","tool_calls":[{"id":"4f736900e","type":"function","function":{"name":"add","arguments":"{\"a\": 2, \"b\": 3}"}},{"id":"c69319726","type":"function","function":{"name":"multiply","arguments":"{\"a\": 2, \"b\": 3}"}}],"role":"assistant"}}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion","usage":{"total_tokens":430,"completion_tokens":128,"prompt_tokens":302},"time_info":{"queue_time":0.003482136,"prompt_time":0.007521096,"completion_time":0.148015855,"total_time":0.16007018089294434,"created":1762855260.7792244}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 523.183584ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1247
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"\nI''ll add and multiply the numbers 2 and 3 for you.\n","tool_calls":[{"id":"4f736900e","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"c69319726","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"4f736900e","role":"tool"},{"content":"6","tool_call_id":"c69319726","role":"tool"}],"model":"zai-org/GLM-4.6:cerebras","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://router.huggingface.co/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: '{"id":"chatcmpl-79f11d7a-dc2b-4e3e-9051-d44712aa2780","choices":[{"finish_reason":"stop","index":0,"message":{"content":"\nThe results are:\n- Addition: 2 + 3 = 5\n- Multiplication: 2 Ć 3 = 6","role":"assistant"}}],"created":1762855280,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion","usage":{"total_tokens":408,"completion_tokens":32,"prompt_tokens":376},"time_info":{"queue_time":0.003082643,"prompt_time":0.008120705,"completion_time":0.030221978,"total_time":0.043164968490600586,"created":1762855280.5628223}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 19.670645958s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/multi_tool_streaming.yaml
new file mode 100644
index 000000000..85ec42ba0
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/multi_tool_streaming.yaml
@@ -0,0 +1,103 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 866
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"zai-org/GLM-4.6:cerebras","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://router.huggingface.co/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-9a97fd4d-1e78-462a-920f-fca9d74b2f42","choices":[{"delta":{"content":"","role":"assistant"},"index":0}],"created":1762855283,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-9a97fd4d-1e78-462a-920f-fca9d74b2f42","choices":[{"delta":{"reasoning":""},"index":0}],"created":1762855283,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-9a97fd4d-1e78-462a-920f-fca9d74b2f42","choices":[{"delta":{"reasoning":""},"index":0}],"created":1762855283,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-9a97fd4d-1e78-462a-920f-fca9d74b2f42","choices":[{"delta":{"content":"\nI"},"index":0}],"created":1762855283,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-9a97fd4d-1e78-462a-920f-fca9d74b2f42","choices":[{"delta":{"content":"'ll add"},"index":0}],"created":1762855283,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-9a97fd4d-1e78-462a-920f-fca9d74b2f42","choices":[{"delta":{"content":" and"},"index":0}],"created":1762855283,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-9a97fd4d-1e78-462a-920f-fca9d74b2f42","choices":[{"delta":{"content":" multiply"},"index":0}],"created":1762855283,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-9a97fd4d-1e78-462a-920f-fca9d74b2f42","choices":[{"delta":{"content":" the numbers 2"},"index":0}],"created":1762855283,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-9a97fd4d-1e78-462a-920f-fca9d74b2f42","choices":[{"delta":{"content":" and 3 for you"},"index":0}],"created":1762855283,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-9a97fd4d-1e78-462a-920f-fca9d74b2f42","choices":[{"delta":{"content":".\n"},"index":0}],"created":1762855283,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-9a97fd4d-1e78-462a-920f-fca9d74b2f42","choices":[{"delta":{"tool_calls":[{"function":{"name":"add","arguments":"{\"a\": 2, \"b\": 3}"},"type":"function","id":"5ffda67d4","index":0},{"function":{"name":"multiply","arguments":"{\"a\": 2, \"b\": 3}"},"type":"function","id":"64c2d22d0","index":1}]},"index":0}],"created":1762855283,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-9a97fd4d-1e78-462a-920f-fca9d74b2f42","choices":[{"delta":{},"finish_reason":"tool_calls","index":0}],"created":1762855283,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk","usage":{"total_tokens":358,"completion_tokens":60,"prompt_tokens":298},"time_info":{"queue_time":0.00408092,"prompt_time":0.006777905,"completion_time":0.048781309,"total_time":0.062016963958740234,"created":1762855283.6442046}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 363.296791ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1284
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"\nI''ll add and multiply the numbers 2 and 3 for you.\n","tool_calls":[{"id":"5ffda67d4","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"64c2d22d0","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"5ffda67d4","role":"tool"},{"content":"6","tool_call_id":"64c2d22d0","role":"tool"}],"model":"zai-org/GLM-4.6:cerebras","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://router.huggingface.co/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-cb515f18-8a70-4aef-88ee-347cc2af9f6d","choices":[{"delta":{"content":"","role":"assistant"},"index":0}],"created":1762855284,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cb515f18-8a70-4aef-88ee-347cc2af9f6d","choices":[{"delta":{"reasoning":""},"index":0}],"created":1762855284,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cb515f18-8a70-4aef-88ee-347cc2af9f6d","choices":[{"delta":{"reasoning":""},"index":0}],"created":1762855284,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cb515f18-8a70-4aef-88ee-347cc2af9f6d","choices":[{"delta":{"content":"\nFor the numbers 2"},"index":0}],"created":1762855284,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cb515f18-8a70-4aef-88ee-347cc2af9f6d","choices":[{"delta":{"content":" and 3:\n\n-"},"index":0}],"created":1762855284,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cb515f18-8a70-4aef-88ee-347cc2af9f6d","choices":[{"delta":{"content":" Addition:"},"index":0}],"created":1762855284,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cb515f18-8a70-4aef-88ee-347cc2af9f6d","choices":[{"delta":{"content":" 2 + 3 = 5\n- Multip"},"index":0}],"created":1762855284,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cb515f18-8a70-4aef-88ee-347cc2af9f6d","choices":[{"delta":{"content":"lication: 2 Ć 3 = 6"},"index":0}],"created":1762855284,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cb515f18-8a70-4aef-88ee-347cc2af9f6d","choices":[{"delta":{},"finish_reason":"stop","index":0}],"created":1762855284,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk","usage":{"total_tokens":409,"completion_tokens":37,"prompt_tokens":372},"time_info":{"queue_time":0.003343426,"prompt_time":0.008747444,"completion_time":0.023277878,"total_time":0.037343502044677734,"created":1762855284.1050324}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 377.104625ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/simple.yaml
new file mode 100644
index 000000000..feb786ac0
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/simple.yaml
@@ -0,0 +1,32 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 174
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"zai-org/GLM-4.6:cerebras","max_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://router.huggingface.co/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: '{"id":"chatcmpl-046a135e-e42b-4078-8359-9d5e76358644","choices":[{"finish_reason":"stop","index":0,"message":{"content":"\nOlĆ”!\n\nHere are the most common ways to say hello in Portuguese, depending on the situation:\n\n### The Most Common \"Hi\"\n\n* **Oi!** (Oh-ee)\n This is the most direct translation of \"hi.\" It''s very common and informal, used with friends and family, especially in **Brazil**. It''s understood in **Portugal** but less common than \"OlĆ”.\"\n\n### The All-Purpose \"Hello\"\n\n* **OlĆ”!** (Oh-LAH)\n This is the most versatile greeting. It can be used in both formal and informal situations, anytime of day, and is common in both **Brazil and Portugal**. If you''re unsure which one to use, \"OlĆ”\" is always a safe choice.\n\n### Greetings by Time of Day\n\nJust like in English, you can greet people based on the time of day. These are used in all Portuguese-speaking countries.\n\n* **Bom dia** (bong DEE-ah) ā Good morning\n* **Boa tarde** (boh-AH tardjee) ā Good afternoon\n* **Boa noite** (boh-AH noytchee) ā Good evening / Good night\n * Note: You use **Boa noite** to greet someone in the evening and also to say goodnight when leaving or going to bed.\n\n### A Quick Summary\n\n| English | Portuguese | Formality | Best for... |\n|:-------------- |:---------------------|:------------------------|:------------------------------------------|\n| Hi | **Oi!** | Informal | Friends, family, casual situations (BR) |\n| Hello | **OlĆ”!** | Formal / Informal | Any situation, anywhere. The safest bet. |\n| Good morning | **Bom dia** | Formal / Informal | Before noon. |\n| Good afternoon | **Boa tarde** | Formal / Informal | From noon until the evening. |\n| Good evening | **Boa noite** | Formal / Informal | In the evening and to say goodnight. |\n\nWant to follow up \"hi\" with \"how are you?\" The most common way is:\n\n* **Tudo bem?** (Too-doh beng?) ā Literally \"Everything well?\" but used as \"How are you?\"","reasoning":"\n1. **Analyze the User''s Request:** The user wants to know how to say \"hi\" in Portuguese. This is a very direct, simple translation request.\n\n2. **Identify the Core Task:** Translate the English word \"hi\" into its Portuguese equivalent(s).\n\n3. **Initial Brainstorming & Keyword Association:**\n * Portuguese.\n * Greeting.\n * \"Hi\".\n * \"Hello\".\n * Informal. Formal.\n * Good morning. Good afternoon. Good evening.\n * What are the variations?\n * In what contexts are they used?\n * Brazil vs. Portugal. Are there differences? (This is a key point for any Romance language).\n\n4. **Structure the Answer:** I want to provide more than just a single word. A good answer will be helpful, clear, and provide context. A good structure would be:\n * Start with the most direct and common answer.\n * Provide alternatives (formal/informal, different times of day).\n * Explain the differences and when to use each one.\n * Mention the Brazil vs. Portugal distinction, as it''s very important for Portuguese.\n * Add a little \"extra\" ā like how to ask \"How are you?\" to make the interaction more natural. This anticipates the user''s next logical question.\n * End with a friendly closing.\n\n5. **Drafting - Section by Section:**\n\n * **Direct Answer (The \"TL;DR\"):** The most common and direct translation of \"hi\" is **\"Oi\"**. I''ll put this first, in bold, to make it stand out immediately.\n\n * **Elaboration on \"Oi\":**\n * Pronunciation: \"oh-ee\". This is crucial for a non-speaker. I should include a simple phonetic guide.\n * Usage: It''s informal, like \"hi\" in English. Used with friends, family, people you know well. It''s very common in Brazil. It''s used in Portugal too, but maybe slightly less than other greetings? (I should double-check this. Yes, it''s understood and used in Portugal, but *OlĆ”* is perhaps more standard/multi-purpose there). I''ll make a note of this.\n\n * **Formal/Basic Greeting:** The equivalent of \"Hello\" is **\"OlĆ”\"**.\n * Pronunciation: \"oh-LAH\". I need to mention the stress on the second syllable.\n * Usage: It''s more versatile than \"Oi\". It can be used in formal and informal situations. It works anytime of day. It''s the safest bet if you''re unsure. It''s extremely common in both Brazil and Portugal.\n\n * **Time-of-Day Greetings:** This is a standard part of Romance languages and very useful for the user.\n * **Bom dia:** \"Good morning.\"\n * **Boa tarde:** \"Good afternoon.\"\n * **Boa noite:** \"Good evening / Good night.\"\n * I should explain that \"Boa noite\" is used both as a greeting in the evening and as a way to say goodbye at night. This is a common point of confusion for English speakers. I''ll explicitly state this.\n * I''ll also add a quick pronunciation guide for each one. This adds a lot of value.\n\n * **Brazil vs. Portugal Nuances:** This is a great \"value-add.\"\n * In **Brazil**: \"Oi\" is super common and informal. \"E aĆ?\" (Eh-eye?) or \"Beleza?\" are very common informal follow-ups, like \"What''s up?\". I should include this to make the greeting more complete and natural.\n * In **Portugal**: \"OlĆ”\" is the most standard. Informal greetings might include \"Viva\" (a bit more enthusiastic/older-fashioned but still used) or simply \"EstĆ” tudo bem?\". I should mention that \"Oi\" is understood but less common than in Brazil. Using \"OlĆ”\" is a safer bet for a tourist.\n\n * **Putting it all together (A summary table/list):** A quick summary helps users scan and find the right option quickly. I''ll create a simple list format:\n\n * **Informal \"Hi\":** Oi (Mostly Brazil, but understood everywhere)\n * **Universal \"Hello\":** OlĆ” (Works in any situation)\n * **By time of day:** Bom dia / Boa tarde / Boa noite\n\n * **Bonus Content:** How to ask \"How are you?\"\n * Common phrase: **Tudo bem?** (Too-doh beng?)\n * Explain it means \"Is everything well?\" or just \"How are you?\".\n * Explain the standard response: **Tudo bem.** (Everything''s well.) or **Tudo bom.** (Everything''s good.) This is a very common exchange and teaching both sides is very helpful.\n\n6. **Review and Refine:** Read through the entire answer.\n * Is it clear? Yes.\n * Is it accurate? Yes.\n * Is it easy to read? The use of bolding, bullet points, and lists helps a lot.\n * Is the tone helpful and friendly? Yes.\n * Did I answer the user''s question directly and also provide useful, related information? Yes. The structure from simple to complex works well. The pronunciation guides are a key feature. The Brazil/Portugal distinction is an important detail. The \"How are you?\" part is a proactive addition.","role":"assistant"}}],"created":1762855217,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion","usage":{"total_tokens":1714,"completion_tokens":1698,"prompt_tokens":16},"time_info":{"queue_time":0.000135781,"prompt_time":0.003248146,"completion_time":2.603353152,"total_time":2.6080667972564697,"created":1762855217.1120505}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.291823958s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/simple_streaming.yaml
new file mode 100644
index 000000000..917ae0d73
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/simple_streaming.yaml
@@ -0,0 +1,736 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 228
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"zai-org/GLM-4.6:cerebras","max_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://router.huggingface.co/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":"","role":"assistant"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"\n"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"1. **Analyze the User's Request"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":":** The user"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"'s request is"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" very simple and direct"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":": \"Say hi in Portuguese\".\n\n"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"2. "},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" **Identify the"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" Core Task:** The core task is"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" to provide the Portuguese translation"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" of"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" the English word"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" \""},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"hi\".\n\n3. **Initial Knowledge"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" Retrie"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"val:** I"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" access my"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" internal knowledge base for translations"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":".\n"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" "},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" * \"Hi\" is an"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" informal greeting"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":".\n"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" * The most"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" common, direct"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":", and informal translation"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" for"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" \"hi"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"\" in Portuguese is \"Oi\".\n"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" * I should"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" also consider other greetings."},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" What"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" are"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" the nuances"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"?\n\n4"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":". **Brainstorm"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" Portuguese G"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"reetings & Their"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" Context"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"s:"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"**\n * **Oi:**"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" This is"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" the most direct equivalent of"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" \""},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"Hi\"."},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" It's informal,"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" used with"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" friends,"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" family, people you"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" know well"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":". It's universally understood"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" in both"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" Brazil"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" and Portugal. This is the primary answer.\n * **OlĆ”:** This is a"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" bit more"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" formal than \""},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"Oi\" but"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" still very"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" common. It's like \""},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"Hello\". It's"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" a safe bet"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" in"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" almost"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" any situation"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":", informal or slightly formal"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"."},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" I should"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" include this as a good alternative"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":".\n * **Bom dia:** This means"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" \"Good morning\". It"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"'s a very common greeting"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":", but it's time"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"-specific."},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" I should"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" mention this. It"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"'s used until"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" around noon"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":".\n"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" "},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" * **Boa tarde:**"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" This means"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" \"Good afternoon\". Also time"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"-specific, used from"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" noon until"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" evening/d"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"usk"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":".\n "},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" * **Boa noite:** This means \"Good evening\" or"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" \"Good night\". It's"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" used from dusk onwards"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" and"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" can be"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" both a"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" greeting"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" and a"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" farewell. This is an"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" important distinction"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" to make.\n"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" * **E aĆ"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"? / Be"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"le"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"za?"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" (Brazil"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"ian slang"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"):"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"** These are"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" very informal"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":", like \""},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"What's"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" up?\"."},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" They are specific to"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" Brazil ("},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"or"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" at least"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" much more"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" common"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" there) and very casual"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"."},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" I should include these to provide"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" more depth"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" and"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" show a better"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" understanding of"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" colloquial"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" language.\n * **"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"Tudo bem"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"?:**"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" Literally"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" \"Is everything"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" well"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"?\". It's used"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" both as"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" a"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" greeting (\"How are"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" you?\") and"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" a response to \""},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"Oi"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"\""},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" or \"OlĆ”\". Worth mentioning"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":".\n\n5."},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" **Structure the Answer:** I need to present this information clearly and concis"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"ely, without"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" overwhelming"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" the user"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":". A good structure would be:\n\n * **Start with"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" the most direct answer:** The"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" user asked"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" for \"hi\", so"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" give them \"Oi\" right away"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":". Make it"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" bold and clear"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":".\n * **Provide the most"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" common alternative:** Give \""},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"OlĆ”\" next as"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" a"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" slightly more"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" formal but very"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" frequent"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" option"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":". Explain the"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" difference in form"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"ality"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":".\n "},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" * **Offer time-specific"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" greetings:** Group \""},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"Bom"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" dia\", \""},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"Boa tarde\", and \"Boa noite\" together and explain"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" when to use"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" them."},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" This is very"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" useful practical"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" information"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":".\n * **Add informal"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"/s"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"lang options"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" (optional"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" but"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" good for value"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"):**"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" Include a couple of"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" very informal"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" options"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" like \"E aĆ?\" and specify"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" that"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" they are"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" more common in Brazil and"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" used with friends"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"."},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" This adds a"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" layer of cultural and"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" linguistic nu"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"ance.\n * **Provide"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" a simple"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" closing:**"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" A friendly closing like \"Hope this"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" helps"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"!\" or just a"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" clean layout"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" is good"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":".\n\n6. **Draft"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" the Content (incorporating the structure):**\n\n * *Initial"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" thought:* \"Oi.\" ->"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" *"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"Too brief"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":". The"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" user might want"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" more"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" context.*\n\n"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" "},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" * *Second draft:"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"*\n The most common"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" way to say"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" \"hi\" in Portuguese is:\n "},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" **Oi!"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"**\n "},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" It's informal,"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" like"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" \""},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"hi,\""},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" and"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" used"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" with friends"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" and family.\n You"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" can also"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" say:\n **OlĆ”!**\n This is"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" more like"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" \"hello"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"\" and"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" can be"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" used in more situations.\n\n"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" * *Refined"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" draft"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" (adding the"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" time"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"-of-day"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" greetings):"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"*\n The most common and direct"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" way to say \"hi\" in Portuguese is:\n"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" **Oi!**\n\n For"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" a slightly"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" more formal or general"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" greeting"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" (like"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" \"hello\"), you can use:\n **OlĆ”!"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"**\n\n You can also"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" use time-of"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"-day"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" greetings, which"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" are"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" very common:\n * **Bom dia** -"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" Good"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" morning\n * **Boa tarde** - Good afternoon\n * **Bo"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"a noite** - Good evening / Good"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" night\n\n *"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" *Final Polish (adding slang and"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" pronunciation/pr"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"actical"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" tips"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"):*\n I'll"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" start with the direct answer"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":", bold"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"ed,"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" for"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" maximum"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" clarity"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":".\n\n "},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" **Oi!** (pronounced"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" roughly \""},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"oy\")\n\n"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" "},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" This is"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" the most common and direct equivalent of"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" \"hi.\""},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" It's"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" informal and used with"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" friends,"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" family,"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" and people you know well.\n\n Here are"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" a few"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" other options,"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" depending on the situation:\n\n **Ol"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"Ć”** ("},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"pronounced \"oh-LAH\")\n "},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" * "},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" This is like \""},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"hello.\" It"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"'s a bit more"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" formal than \""},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"Oi\" but still very common and works"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" in"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" almost any situation.\n\n You can"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" also use greetings based"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" on the"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" time of day:\n * **Bom dia** - Good"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" morning\n * **Boa tarde** - Good afternoon"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"\n * **Boa noite** - Good evening / Good night\n\n And for"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" very informal"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" situations with"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" friends"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" (especially in"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" Brazil):\n *"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" **E aĆ?** - What"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"'s up?\n *"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" **Tudo bem"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"?** - How's it"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" going? / Everything"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" okay"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"?\n\n"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"7."},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" **Review and Final"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"ize:** The final draft"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" is excellent."},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" It's comprehensive but"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" not"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" overwhelming. It gives the"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" direct answer first,"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" then provides context,"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" alternatives,"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" and cultural nuances."},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" The pronunciation guides"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" are"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" a helpful"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" touch."},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" The formatting with"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" bold"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" text and"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" bullet points"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" makes it easy to read. This is"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" the version"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":" I'll output"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"reasoning":"."},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":"\nThe most"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":" common way to say \"hi"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":"\" in Portuguese is:\n\n**Oi!**\n\nIt's"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":" informal, just like"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":" \"hi,\" and is used with friends, family"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":", and people you know well.\n\nHere are a"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":" few other options:\n\n* "},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":" **OlĆ”** -"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":" This is like \"hello"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":".\" It's"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":" a bit more formal than *Oi"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":"* but works in almost"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":" any situation.\n\nYou"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":" can also use greetings based"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":" on the time of day"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":":\n\n* **Bom"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":" dia** - Good morning\n* **Boa tarde** - Good afternoon\n* **Bo"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{"content":"a noite** - Good evening / Good night"},"index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-6e7970f4-2fbf-43c3-9847-3fc8717703e9","choices":[{"delta":{},"finish_reason":"stop","index":0}],"created":1762855220,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk","usage":{"total_tokens":1337,"completion_tokens":1321,"prompt_tokens":16},"time_info":{"queue_time":0.00012731,"prompt_time":0.004064561,"completion_time":1.739690271,"total_time":1.7457032203674316,"created":1762855220.2438056}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 319.948458ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/tool.yaml
new file mode 100644
index 000000000..997510596
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/tool.yaml
@@ -0,0 +1,61 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 466
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"zai-org/GLM-4.6:cerebras","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://router.huggingface.co/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: '{"id":"chatcmpl-9ed5d57c-2570-4ccd-8a72-6f22c8577e98","choices":[{"finish_reason":"tool_calls","index":0,"message":{"content":"\nI''ll get the weather information for Florence, Italy for you.\n","reasoning":"The user is asking for weather information for Florence, Italy. I need to use the weather function with the location parameter. The user specified \"Florence,Italy\" which I should use exactly as provided, or I could use just \"Florence\" since that''s the city name. Let me check the function parameters - it requires a \"location\" parameter which is described as \"the city\". I think \"Florence\" would be sufficient, but since they specifically included \"Italy\" I should probably use \"Florence,Italy\" to be more precise.","tool_calls":[{"id":"17412c140","type":"function","function":{"name":"weather","arguments":"{\"location\": \"Florence,Italy\"}"}}],"role":"assistant"}}],"created":1762855222,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion","usage":{"total_tokens":331,"completion_tokens":144,"prompt_tokens":187},"time_info":{"queue_time":0.005854158,"prompt_time":0.008443714,"completion_time":0.295474428,"total_time":0.3114504814147949,"created":1762855222.3435056}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 688.961166ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 756
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"\nI''ll get the weather information for Florence, Italy for you.\n","tool_calls":[{"id":"17412c140","function":{"arguments":"{\"location\": \"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"17412c140","role":"tool"}],"model":"zai-org/GLM-4.6:cerebras","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://router.huggingface.co/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: '{"id":"chatcmpl-6e9e46c1-c111-4fc0-8648-8dffcbf32a72","choices":[{"finish_reason":"stop","index":0,"message":{"content":"\nThe weather in Florence, Italy is currently 40°C (which is quite hot - about 104°F). This is very warm weather, so if you''re planning to be outdoors there, you''ll want to stay hydrated and seek shade when possible.","role":"assistant"}}],"created":1762855242,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion","usage":{"total_tokens":282,"completion_tokens":54,"prompt_tokens":228},"time_info":{"queue_time":0.004272864,"prompt_time":0.004543828,"completion_time":0.094835176,"total_time":0.105194091796875,"created":1762855242.5629983}}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 20.019286708s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/tool_streaming.yaml
new file mode 100644
index 000000000..d1eb7cec3
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/tool_streaming.yaml
@@ -0,0 +1,229 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 520
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"zai-org/GLM-4.6:cerebras","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://router.huggingface.co/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"content":"","role":"assistant"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":""},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":"The user is"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" asking"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" for weather information"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" for Florence, Italy. I need to use the weather function with"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" the"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" location parameter."},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" The"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" user specified"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" \""},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":"Florence"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":",Italy\" as"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" the location. I"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" should"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" use"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" this"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" exactly as"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" provided since"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" it"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" includes both"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" the"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" city and country information which"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" will"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" help"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" get"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":" accurate results"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":"."},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"reasoning":""},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"content":"\n"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"content":"I'll get the"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"content":" weather information for Florence, Italy for you.\n"},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{"tool_calls":[{"function":{"name":"weather","arguments":"{\"location\": \"Florence,Italy\"}"},"type":"function","id":"75314f724","index":0}]},"index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-cd1b3de5-3a2b-4246-ba7f-583eb2eddfbd","choices":[{"delta":{},"finish_reason":"tool_calls","index":0}],"created":1762855240,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk","usage":{"total_tokens":279,"completion_tokens":92,"prompt_tokens":187},"time_info":{"queue_time":0.004136448,"prompt_time":0.005123835,"completion_time":0.16235391,"total_time":0.17365789413452148,"created":1762855240.359195}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 348.470333ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 810
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"\nI''ll get the weather information for Florence, Italy for you.\n","tool_calls":[{"id":"75314f724","function":{"arguments":"{\"location\": \"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"75314f724","role":"tool"}],"model":"zai-org/GLM-4.6:cerebras","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://router.huggingface.co/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":"","role":"assistant"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"reasoning":""},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"reasoning":""},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":"\nThe current weather"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" in Florence, Italy"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" is"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" 40°C, which"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" is"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" quite"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" hot"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":"!"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" This"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" is"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" a"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" very"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" warm"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" temperature"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":","},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" so"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" if"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" you"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":"'re"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" planning"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" to"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" visit"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" or"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" have"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" activities"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" planned"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" there"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":","},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" you"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":"'ll"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" want"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" to"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" be"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" prepared"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" for"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" the"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" heat"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":"."},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" Make"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" sure"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" to"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" stay"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" hydrated and seek shade"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" when"},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{"content":" possible."},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{},"index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk"}
+
+ data: {"id":"chatcmpl-7aa67568-b556-4b17-b0a9-5cd878985e99","choices":[{"delta":{},"finish_reason":"stop","index":0}],"created":1762855260,"model":"zai-glm-4.6","system_fingerprint":"fp_b78e4418d824cdcd64e8","object":"chat.completion.chunk","usage":{"total_tokens":290,"completion_tokens":62,"prompt_tokens":228},"time_info":{"queue_time":0.003050024,"prompt_time":0.003663248,"completion_time":0.23331325,"total_time":0.24212312698364258,"created":1762855260.1703784}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 19.633745459s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/llama-cpp-gpt-oss/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/llama-cpp-gpt-oss/simple.yaml
new file mode 100644
index 000000000..0ab835e29
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/llama-cpp-gpt-oss/simple.yaml
@@ -0,0 +1,32 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 179
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"openai/gpt-oss-20b","max_completion_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: http://localhost:8080/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 760
+ body: '{"choices":[{"finish_reason":"stop","index":0,"message":{"role":"assistant","reasoning_content":"The user says: \"Say hi in Portuguese\". So answer: \"OlĆ”\" or \"Oi\". Likely \"OlĆ”\". Probably a friendly greeting. Just respond with that.","content":"OlĆ”!"}}],"created":1762855698,"model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion","usage":{"completion_tokens":47,"prompt_tokens":84,"total_tokens":131},"id":"chatcmpl-vR6SJg5NfJyDqhfDG37wzJGDJtoLvF2f","timings":{"cache_n":0,"prompt_n":84,"prompt_ms":292.377,"prompt_per_token_ms":3.4806785714285717,"prompt_per_second":287.3003006392431,"predicted_n":47,"predicted_ms":391.773,"predicted_per_token_ms":8.335595744680852,"predicted_per_second":119.96743011897196}}'
+ headers:
+ Content-Type:
+ - application/json; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 687.964334ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/llama-cpp-gpt-oss/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/llama-cpp-gpt-oss/simple_streaming.yaml
new file mode 100644
index 000000000..9d2acfe76
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/llama-cpp-gpt-oss/simple_streaming.yaml
@@ -0,0 +1,136 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 233
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"openai/gpt-oss-20b","max_completion_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: http://localhost:8080/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ transfer_encoding:
+ - chunked
+ content_length: -1
+ body: |+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"role":"assistant","content":null}}],"created":1762855698,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"The"}}],"created":1762855698,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" user"}}],"created":1762855698,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":":"}}],"created":1762855698,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" \""}}],"created":1762855698,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"Say"}}],"created":1762855698,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" hi"}}],"created":1762855698,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" in"}}],"created":1762855698,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" Portuguese"}}],"created":1762855698,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"\"."}}],"created":1762855698,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" They"}}],"created":1762855698,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" want"}}],"created":1762855698,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" a"}}],"created":1762855698,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" greeting"}}],"created":1762855698,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" in"}}],"created":1762855698,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" Portuguese"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"."}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" Simple"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":":"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" \""}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"OlĆ”"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"!\""}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" or"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" \""}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"Oi"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"!\"."}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" Probably"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" respond"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" with"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" \""}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"OlĆ”"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"!\""}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" or"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" \""}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"Oi"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"!"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"\"."}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"\n\nWe"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" should"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" keep"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" it"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" concise"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"."}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" We'll"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" respond"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"."}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":"OlĆ”"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":"!"}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":"stop","index":0,"delta":{}}],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[],"created":1762855699,"id":"chatcmpl-rd0JN5fzYlCrafuJEy6psZhukXbBVmTK","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk","usage":{"completion_tokens":57,"prompt_tokens":84,"total_tokens":141},"timings":{"cache_n":83,"prompt_n":1,"prompt_ms":8.996,"prompt_per_token_ms":8.996,"prompt_per_second":111.16051578479323,"predicted_n":57,"predicted_ms":484.01,"predicted_per_token_ms":8.49140350877193,"predicted_per_second":117.76616185616001}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 755.667µs
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/llama-cpp-gpt-oss/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/llama-cpp-gpt-oss/tool.yaml
new file mode 100644
index 000000000..10d82e6f8
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/llama-cpp-gpt-oss/tool.yaml
@@ -0,0 +1,61 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 471
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"openai/gpt-oss-20b","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: http://localhost:8080/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 914
+ body: '{"choices":[{"finish_reason":"tool_calls","index":0,"message":{"role":"assistant","reasoning_content":"The user asks: \"What''s the weather in Florence, Italy?\" We have a tool \"functions.weather\" that can get weather information. We should call it.","content":null,"tool_calls":[{"type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence,Italy\"}"},"id":"mvVq65j66dyGRizURhbdNCEnSO56GhXx"}]}}],"created":1762855699,"model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion","usage":{"completion_tokens":58,"prompt_tokens":139,"total_tokens":197},"id":"chatcmpl-xN1fVcGhqAh4SXLdsus63WtY5KhK0cv8","timings":{"cache_n":59,"prompt_n":80,"prompt_ms":138.363,"prompt_per_token_ms":1.7295375,"prompt_per_second":578.1892557981541,"predicted_n":58,"predicted_ms":483.677,"predicted_per_token_ms":8.339258620689655,"predicted_per_second":119.91473648736657}}'
+ headers:
+ Content-Type:
+ - application/json; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 625.633ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 898
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"mvVq65j66dyGRizURhbdNCEnSO56GhXx","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_content":"The user asks: \"What''s the weather in Florence, Italy?\" We have a tool \"functions.weather\" that can get weather information. We should call it."},{"content":"40 C","tool_call_id":"mvVq65j66dyGRizURhbdNCEnSO56GhXx","role":"tool"}],"model":"openai/gpt-oss-20b","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: http://localhost:8080/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 646
+ body: '{"choices":[{"finish_reason":"stop","index":0,"message":{"role":"assistant","content":"The current weather in Florence, Italy is **40āÆĀ°C**."}}],"created":1762855700,"model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion","usage":{"completion_tokens":18,"prompt_tokens":213,"total_tokens":231},"id":"chatcmpl-mt9KdP2gwDDiYYxdoehItCfCj6J1HNjs","timings":{"cache_n":177,"prompt_n":36,"prompt_ms":79.143,"prompt_per_token_ms":2.1984166666666667,"prompt_per_second":454.8728251393048,"predicted_n":18,"predicted_ms":144.84,"predicted_per_token_ms":8.046666666666667,"predicted_per_second":124.27506213753105}}'
+ headers:
+ Content-Type:
+ - application/json; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 225.614042ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/llama-cpp-gpt-oss/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/llama-cpp-gpt-oss/tool_streaming.yaml
new file mode 100644
index 000000000..589df587f
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/llama-cpp-gpt-oss/tool_streaming.yaml
@@ -0,0 +1,155 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 525
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"openai/gpt-oss-20b","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: http://localhost:8080/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ transfer_encoding:
+ - chunked
+ content_length: -1
+ body: |+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"role":"assistant","content":null}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"User"}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" wants"}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" weather"}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" in"}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" Florence"}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":","}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" Italy"}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"."}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" We"}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" can"}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" use"}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" the"}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" weather"}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" function"}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"."}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"tool_calls":[{"index":0,"id":"g2KOIWzn722hzEaZQmNVP4roUPEiYafL","type":"function","function":{"name":"weather","arguments":"{\""}}]}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"location"}}]}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Flor"}}]}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"ence"}}]}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":","}}]}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" Italy"}}]}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"}"}}]}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":"tool_calls","index":0,"delta":{}}],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[],"created":1762855700,"id":"chatcmpl-lz25qRqbjeLO8nbwF4DJYJQc7KjZrG2z","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk","usage":{"completion_tokens":41,"prompt_tokens":139,"total_tokens":180},"timings":{"cache_n":138,"prompt_n":1,"prompt_ms":8.691,"prompt_per_token_ms":8.691,"prompt_per_second":115.06155793349441,"predicted_n":41,"predicted_ms":339.279,"predicted_per_token_ms":8.27509756097561,"predicted_per_second":120.84449671214546}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 859.5µs
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 877
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"g2KOIWzn722hzEaZQmNVP4roUPEiYafL","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_content":"User wants weather in Florence, Italy. We can use the weather function."},{"content":"40 C","tool_call_id":"g2KOIWzn722hzEaZQmNVP4roUPEiYafL","role":"tool"}],"model":"openai/gpt-oss-20b","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: http://localhost:8080/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ transfer_encoding:
+ - chunked
+ content_length: -1
+ body: |+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"role":"assistant","content":null}}],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":"The"}}],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":" current"}}],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":" weather"}}],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":" in"}}],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":" Florence"}}],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":","}}],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":" Italy"}}],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":" is"}}],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":" **"}}],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":"40"}}],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":"āÆ"}}],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":"°C"}}],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":"**"}}],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":"."}}],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":"stop","index":0,"delta":{}}],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[],"created":1762855700,"id":"chatcmpl-PRVO688pTstdVIzbBa8S5l5QzcgoxAWl","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk","usage":{"completion_tokens":18,"prompt_tokens":196,"total_tokens":214},"timings":{"cache_n":160,"prompt_n":36,"prompt_ms":79.853,"prompt_per_token_ms":2.218138888888889,"prompt_per_second":450.8283971798179,"predicted_n":18,"predicted_ms":145.366,"predicted_per_token_ms":8.07588888888889,"predicted_per_second":123.82537869928318}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.05025ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/multi_tool.yaml
new file mode 100644
index 000000000..40c7e785d
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 816
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"grok-4-fast","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"dec7a509-fc2a-5adb-eed9-626affdd1430","object":"chat.completion","created":1762854946,"model":"grok-4-fast-reasoning","choices":[{"index":0,"message":{"role":"assistant","content":"","tool_calls":[{"id":"call_77946408","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"},"type":"function"},{"id":"call_90297600","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"},"type":"function"}],"refusal":null},"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":437,"completion_tokens":68,"total_tokens":648,"prompt_tokens_details":{"text_tokens":437,"audio_tokens":0,"image_tokens":0,"cached_tokens":304},"completion_tokens_details":{"reasoning_tokens":143,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_bfbe7bd0a2"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.687079417s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1177
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_77946408","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"call_90297600","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"call_77946408","role":"tool"},{"content":"6","tool_call_id":"call_90297600","role":"tool"}],"model":"grok-4-fast","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"bfde0945-c590-ce6c-b493-8f7f3fced601","object":"chat.completion","created":1762854948,"model":"grok-4-fast-reasoning","choices":[{"index":0,"message":{"role":"assistant","content":"The sum of 2 and 3 is 5. \nThe product of 2 and 3 is 6.","refusal":null},"finish_reason":"stop"}],"usage":{"prompt_tokens":666,"completion_tokens":25,"total_tokens":734,"prompt_tokens_details":{"text_tokens":666,"audio_tokens":0,"image_tokens":0,"cached_tokens":304},"completion_tokens_details":{"reasoning_tokens":43,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_bfbe7bd0a2"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.056138584s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/multi_tool_streaming.yaml
new file mode 100644
index 000000000..3e834deae
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/multi_tool_streaming.yaml
@@ -0,0 +1,493 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 853
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"grok-4-fast","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"role":"assistant"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854950,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854951,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854951,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854951,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854951,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854951,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854951,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854951,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854951,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854951,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854951,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854951,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854951,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_87057118","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"},"index":0,"type":"function"}]}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854951,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_52998358","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"},"index":1,"type":"function"}]}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854951,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"b4b9e8e9-d0a8-fea3-52ae-7c4c33004f65","object":"chat.completion.chunk","created":1762854951,"model":"grok-4-fast-reasoning","choices":[],"usage":{"prompt_tokens":433,"completion_tokens":68,"total_tokens":645,"prompt_tokens_details":{"text_tokens":433,"audio_tokens":0,"image_tokens":0,"cached_tokens":403},"completion_tokens_details":{"reasoning_tokens":144,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 415.14375ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1214
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_87057118","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"call_52998358","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"call_87057118","role":"tool"},{"content":"6","tool_call_id":"call_52998358","role":"tool"}],"model":"grok-4-fast","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"role":"assistant"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"The"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" sum"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" of"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" "}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"2"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" and"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" "}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"3"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" is"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" "}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"5"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"."}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" \n"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"The"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" product"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" of"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" "}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"2"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" and"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" "}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"3"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" is"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" "}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"6"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"."}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"0ba115c8-62ec-046d-5111-ef980f20296a","object":"chat.completion.chunk","created":1762854952,"model":"grok-4-fast-reasoning","choices":[],"usage":{"prompt_tokens":663,"completion_tokens":25,"total_tokens":727,"prompt_tokens_details":{"text_tokens":663,"audio_tokens":0,"image_tokens":0,"cached_tokens":611},"completion_tokens_details":{"reasoning_tokens":39,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 455.97875ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/simple.yaml
new file mode 100644
index 000000000..625e0d2ec
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 161
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"grok-4-fast","max_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"ba921086-b431-a891-6539-f253e188df6f","object":"chat.completion","created":1762854936,"model":"grok-4-fast-reasoning","choices":[{"index":0,"message":{"role":"assistant","content":"OlĆ”!","refusal":null},"finish_reason":"stop"}],"usage":{"prompt_tokens":165,"completion_tokens":2,"total_tokens":244,"prompt_tokens_details":{"text_tokens":165,"audio_tokens":0,"image_tokens":0,"cached_tokens":150},"completion_tokens_details":{"reasoning_tokens":77,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_bfbe7bd0a2"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 928.874459ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/simple_streaming.yaml
new file mode 100644
index 000000000..7f8ecdfc6
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/simple_streaming.yaml
@@ -0,0 +1,320 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 215
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"grok-4-fast","max_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"role":"assistant"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854937,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"OlĆ”"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"!"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"bd8fcffa-eabb-78dc-6980-d22e46ee7cea","object":"chat.completion.chunk","created":1762854938,"model":"grok-4-fast-reasoning","choices":[],"usage":{"prompt_tokens":165,"completion_tokens":2,"total_tokens":306,"prompt_tokens_details":{"text_tokens":165,"audio_tokens":0,"image_tokens":0,"cached_tokens":150},"completion_tokens_details":{"reasoning_tokens":139,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 198.825167ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/tool.yaml
new file mode 100644
index 000000000..1da4dad20
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 453
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"grok-4-fast","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"6645739c-32ed-3f7b-3df7-eae6c86bee88","object":"chat.completion","created":1762854938,"model":"grok-4-fast-reasoning","choices":[{"index":0,"message":{"role":"assistant","content":"","tool_calls":[{"id":"call_38088650","function":{"name":"weather","arguments":"{\"location\":\"Florence, Italy\"}"},"type":"function"}],"refusal":null},"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":361,"completion_tokens":26,"total_tokens":527,"prompt_tokens_details":{"text_tokens":361,"audio_tokens":0,"image_tokens":0,"cached_tokens":304},"completion_tokens_details":{"reasoning_tokens":140,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_bfbe7bd0a2"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.622645042s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 673
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_38088650","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_38088650","role":"tool"}],"model":"grok-4-fast","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"8359b4aa-22c3-dfe0-c3b5-9e622b2be670","object":"chat.completion","created":1762854941,"model":"grok-4-fast-reasoning","choices":[{"index":0,"message":{"role":"assistant","content":"The current temperature in Florence, Italy, is 40°C. If you need more details like forecasts or conditions, let me know!","refusal":null},"finish_reason":"stop"}],"usage":{"prompt_tokens":540,"completion_tokens":27,"total_tokens":661,"prompt_tokens_details":{"text_tokens":540,"audio_tokens":0,"image_tokens":0,"cached_tokens":304},"completion_tokens_details":{"reasoning_tokens":94,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_bfbe7bd0a2"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.701426875s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/tool_streaming.yaml
new file mode 100644
index 000000000..1080ad3ec
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-4-fast/tool_streaming.yaml
@@ -0,0 +1,671 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 507
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"grok-4-fast","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"role":"assistant"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854943,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_54240681","function":{"name":"weather","arguments":"{\"location\":\"Florence, Italy\"}"},"index":0,"type":"function"}]}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"86dec149-d152-1223-0b58-aaea2004fdc1","object":"chat.completion.chunk","created":1762854944,"model":"grok-4-fast-reasoning","choices":[],"usage":{"prompt_tokens":361,"completion_tokens":26,"total_tokens":607,"prompt_tokens_details":{"text_tokens":361,"audio_tokens":0,"image_tokens":0,"cached_tokens":304},"completion_tokens_details":{"reasoning_tokens":220,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 182.838541ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 727
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_54240681","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_54240681","role":"tool"}],"model":"grok-4-fast","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"role":"assistant"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"The"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" current"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" weather"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" in"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" Florence"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":","}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" Italy"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":","}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" is"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" "}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"40"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"°C"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" ("}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"104"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"°F"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":")."}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" It's"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" quite"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" hot"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"ā"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"stay"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" hydrated"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" and"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" seek"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" shade"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" if"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" you're"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" out"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" and"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" about"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"!"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" If"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" you"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" need"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" more"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" details"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" like"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" forecasts"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" or"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" humidity"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":","}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" let"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" me"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":" know"}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{"content":"."}}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: {"id":"653a2216-e941-bdf0-0fa3-efe1681b9405","object":"chat.completion.chunk","created":1762854945,"model":"grok-4-fast-reasoning","choices":[],"usage":{"prompt_tokens":620,"completion_tokens":45,"total_tokens":698,"prompt_tokens_details":{"text_tokens":620,"audio_tokens":0,"image_tokens":0,"cached_tokens":365},"completion_tokens_details":{"reasoning_tokens":33,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_bfbe7bd0a2"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 188.3925ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/multi_tool.yaml
new file mode 100644
index 000000000..fc3e5ee74
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 821
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"grok-code-fast-1","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"9874b007-2b46-d81c-99af-a1e5f79ad5f8","object":"chat.completion","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"message":{"role":"assistant","content":"","tool_calls":[{"id":"call_20392219","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"},"type":"function"},{"id":"call_35218664","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"},"type":"function"}],"refusal":null},"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":471,"completion_tokens":68,"total_tokens":773,"prompt_tokens_details":{"text_tokens":471,"audio_tokens":0,"image_tokens":0,"cached_tokens":320},"completion_tokens_details":{"reasoning_tokens":234,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_10f00c862d"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.281730792s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1182
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_20392219","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"call_35218664","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"call_20392219","role":"tool"},{"content":"6","tool_call_id":"call_35218664","role":"tool"}],"model":"grok-code-fast-1","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"7ecd4565-51f1-24db-578f-628fc2c2dc35","object":"chat.completion","created":1762854968,"model":"grok-code-fast-1","choices":[{"index":0,"message":{"role":"assistant","content":"2 + 3 = 5 \n2 * 3 = 6","refusal":null},"finish_reason":"stop"}],"usage":{"prompt_tokens":791,"completion_tokens":15,"total_tokens":849,"prompt_tokens_details":{"text_tokens":791,"audio_tokens":0,"image_tokens":0,"cached_tokens":320},"completion_tokens_details":{"reasoning_tokens":43,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_10f00c862d"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.158569583s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/multi_tool_streaming.yaml
new file mode 100644
index 000000000..1e2065e33
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/multi_tool_streaming.yaml
@@ -0,0 +1,601 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 858
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"grok-code-fast-1","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"The","role":"assistant"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" user"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" asked"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" to"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" add"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" and"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" multiply"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" "}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"2"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" and"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" "}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"3"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"."}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" I"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" need"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" to"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" use"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" both"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" tools"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":":"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" add"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" and"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" multiply"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":".\n"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854969,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_28204233","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"},"index":0,"type":"function"}]}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_72666071","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"},"index":1,"type":"function"}]}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"f4589f03-c781-01f2-4824-8406d4201043","object":"chat.completion.chunk","created":1762854970,"model":"grok-code-fast-1","choices":[],"usage":{"prompt_tokens":467,"completion_tokens":68,"total_tokens":719,"prompt_tokens_details":{"text_tokens":467,"audio_tokens":0,"image_tokens":0,"cached_tokens":384},"completion_tokens_details":{"reasoning_tokens":184,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_10f00c862d"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 195.743ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1331
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_28204233","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"call_72666071","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant","reasoning_content":"The user asked to add and multiply 2 and 3. I need to use both tools: add and multiply.\n"},{"content":"5","tool_call_id":"call_28204233","role":"tool"},{"content":"6","tool_call_id":"call_72666071","role":"tool"}],"model":"grok-code-fast-1","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"I","role":"assistant"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" have"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" results"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":":"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" add"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" gave"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" "}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"5"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" multiply"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" gave"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" "}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"6"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":".\n"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854971,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"The"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" sum"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" of"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" "}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"2"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" and"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" "}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"3"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" is"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" "}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"5"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"."}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" \n"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"The"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" product"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" of"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" "}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"2"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" and"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" "}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"3"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" is"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" "}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"6"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"."}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"636c757c-c4b5-337d-9b69-dddd3b8e84b5","object":"chat.completion.chunk","created":1762854973,"model":"grok-code-fast-1","choices":[],"usage":{"prompt_tokens":737,"completion_tokens":25,"total_tokens":815,"prompt_tokens_details":{"text_tokens":737,"audio_tokens":0,"image_tokens":0,"cached_tokens":640},"completion_tokens_details":{"reasoning_tokens":53,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_10f00c862d"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 166.444625ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/simple.yaml
new file mode 100644
index 000000000..92f93a78d
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 166
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"grok-code-fast-1","max_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"3d4e99a3-243f-88eb-3ebf-9bba327ac44b","object":"chat.completion","created":1762854952,"model":"grok-code-fast-1","choices":[{"index":0,"message":{"role":"assistant","content":"OlĆ”! (That''s \"hi\" in Portuguese. For a more informal vibe, you can use \"Oi!\".)","refusal":null},"finish_reason":"stop"}],"usage":{"prompt_tokens":213,"completion_tokens":23,"total_tokens":414,"prompt_tokens_details":{"text_tokens":213,"audio_tokens":0,"image_tokens":0,"cached_tokens":192},"completion_tokens_details":{"reasoning_tokens":178,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_10f00c862d"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 4.059811333s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/simple_streaming.yaml
new file mode 100644
index 000000000..a723dbbdd
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/simple_streaming.yaml
@@ -0,0 +1,458 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 220
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"grok-code-fast-1","max_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"First","role":"assistant"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" user"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" said"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":":"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"Say"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" hi"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" in"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" Portuguese"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":".\""}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" This"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" is"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" a"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" simple"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" request"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" to"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" translate"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" or"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" say"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"hi"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"\""}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" in"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" Portuguese"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":".\n"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854957,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"\n\n## Understanding user request \n- The user asked to say \"hi\" in Portuguese, a straightforward translation request."}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"Oi"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"!"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" ("}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"That's"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" \""}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"hi"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"\""}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" in"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" Portuguese"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":".)"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"e34db796-8dc4-24e9-2b49-613698c2c1d6","object":"chat.completion.chunk","created":1762854958,"model":"grok-code-fast-1","choices":[],"usage":{"prompt_tokens":213,"completion_tokens":10,"total_tokens":423,"prompt_tokens_details":{"text_tokens":213,"audio_tokens":0,"image_tokens":0,"cached_tokens":192},"completion_tokens_details":{"reasoning_tokens":200,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_10f00c862d"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 195.607084ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/tool.yaml
new file mode 100644
index 000000000..bdf3632f0
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 458
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"grok-code-fast-1","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"55c3d80a-b267-c2cb-8a03-387402a2fe4f","object":"chat.completion","created":1762854959,"model":"grok-code-fast-1","choices":[{"index":0,"message":{"role":"assistant","content":"","tool_calls":[{"id":"call_27103959","function":{"name":"weather","arguments":"{\"location\":\"Florence,Italy\"}"},"type":"function"}],"refusal":null},"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":390,"completion_tokens":26,"total_tokens":537,"prompt_tokens_details":{"text_tokens":390,"audio_tokens":0,"image_tokens":0,"cached_tokens":320},"completion_tokens_details":{"reasoning_tokens":121,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_10f00c862d"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.562176375s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 677
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_27103959","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_27103959","role":"tool"}],"model":"grok-code-fast-1","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"87f13718-fb6b-512d-cf9d-969f79138225","object":"chat.completion","created":1762854961,"model":"grok-code-fast-1","choices":[{"index":0,"message":{"role":"assistant","content":"The current temperature in Florence, Italy is 40°C.","refusal":null},"finish_reason":"stop"}],"usage":{"prompt_tokens":550,"completion_tokens":12,"total_tokens":702,"prompt_tokens_details":{"text_tokens":550,"audio_tokens":0,"image_tokens":0,"cached_tokens":512},"completion_tokens_details":{"reasoning_tokens":140,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_10f00c862d"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.857338583s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/tool_streaming.yaml
new file mode 100644
index 000000000..fbb9aabfe
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/xai-grok-code-fast/tool_streaming.yaml
@@ -0,0 +1,393 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 512
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"grok-code-fast-1","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"The","role":"assistant"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" user"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" asked"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":":"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"What's"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" weather"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" in"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" Florence"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"Italy"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"?\"\n"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854963,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_64629939","function":{"name":"weather","arguments":"{\"location\":\"Florence,Italy\"}"},"index":0,"type":"function"}]}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"ba8d6fcb-acbd-9d88-c17c-8ddef4027734","object":"chat.completion.chunk","created":1762854964,"model":"grok-code-fast-1","choices":[],"usage":{"prompt_tokens":390,"completion_tokens":26,"total_tokens":495,"prompt_tokens_details":{"text_tokens":390,"audio_tokens":0,"image_tokens":0,"cached_tokens":384},"completion_tokens_details":{"reasoning_tokens":79,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_10f00c862d"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 226.151666ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 813
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_64629939","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_content":"The user asked: \"What''s the weather in Florence,Italy?\"\n"},{"content":"40 C","tool_call_id":"call_64629939","role":"tool"}],"model":"grok-code-fast-1","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"The","role":"assistant"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" tool"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" returned"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"40"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" C"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"\","}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" which"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" means"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" "}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":"40"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" degrees"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":" Celsius"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"reasoning_content":".\n"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"The"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" current"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" weather"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" in"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" Florence"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":","}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" Italy"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" is"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":" "}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"40"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"°C"}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{"content":"."}}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"system_fingerprint":"fp_10f00c862d"}
+
+ data: {"id":"438e92b5-a71d-8052-6667-f9db15f43cbe","object":"chat.completion.chunk","created":1762854965,"model":"grok-code-fast-1","choices":[],"usage":{"prompt_tokens":508,"completion_tokens":12,"total_tokens":588,"prompt_tokens_details":{"text_tokens":508,"audio_tokens":0,"image_tokens":0,"cached_tokens":448},"completion_tokens_details":{"reasoning_tokens":68,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_10f00c862d"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 431.66775ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/multi_tool.yaml
new file mode 100644
index 000000000..34c00b2b4
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 812
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"glm-4.5","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"choices":[{"finish_reason":"tool_calls","index":0,"message":{"content":"\nI''ll add and multiply the numbers 2 and 3 for you.\n","reasoning_content":"\nThe user is asking me to add and multiply the numbers 2 and 3. I need to use both the add and multiply functions as instructed. Let me make both function calls:\n\n1. Add 2 and 3\n2. Multiply 2 and 3\n\nBoth functions require two integer parameters, and I have the values 2 and 3 to use.","role":"assistant","tool_calls":[{"function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"id":"call_-8167732570302206983","index":0,"type":"function"},{"function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"id":"call_-8167732570302206982","index":1,"type":"function"}]}}],"created":1762855007,"id":"20251111175641bcb6bdd6085647a6","model":"glm-4.5","request_id":"20251111175641bcb6bdd6085647a6","usage":{"completion_tokens":136,"prompt_tokens":286,"prompt_tokens_details":{"cached_tokens":43},"total_tokens":422}}'
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 6.3064855s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1600
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"\nI''ll add and multiply the numbers 2 and 3 for you.\n","tool_calls":[{"id":"call_-8167732570302206983","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"call_-8167732570302206982","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant","reasoning_content":"\nThe user is asking me to add and multiply the numbers 2 and 3. I need to use both the add and multiply functions as instructed. Let me make both function calls:\n\n1. Add 2 and 3\n2. Multiply 2 and 3\n\nBoth functions require two integer parameters, and I have the values 2 and 3 to use."},{"content":"5","tool_call_id":"call_-8167732570302206983","role":"tool"},{"content":"6","tool_call_id":"call_-8167732570302206982","role":"tool"}],"model":"glm-4.5","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"choices":[{"finish_reason":"stop","index":0,"message":{"content":"\nThe results are:\n- Addition: 2 + 3 = 5\n- Multiplication: 2 Ć 3 = 6","reasoning_content":"\nGreat! I got the results from both function calls:\n- Adding 2 and 3 gives 5\n- Multiplying 2 and 3 gives 6\n\nI should present both results to the user clearly.","role":"assistant"}}],"created":1762855010,"id":"2025111117564736d87595a2214e40","model":"glm-4.5","request_id":"2025111117564736d87595a2214e40","usage":{"completion_tokens":77,"prompt_tokens":435,"prompt_tokens_details":{"cached_tokens":43},"total_tokens":512}}'
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 2.935906041s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/multi_tool_streaming.yaml
new file mode 100644
index 000000000..f22a80219
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/multi_tool_streaming.yaml
@@ -0,0 +1,415 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 849
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"glm-4.5","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"The"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" user"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" wants"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" me"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" to"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" both"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" add"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" and"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" multiply"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" numbers"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"2"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" and"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"3"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" I"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" need"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" to"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" use"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" both"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" add"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" and"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" multiply"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" functions"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" with"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" these"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" parameters"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":".\n\n"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"For"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" add"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" function"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":\n"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" a"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"2"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" b"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"3"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n\n"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"For"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" multiply"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" function"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":\n"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" a"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"2"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" \n"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" b"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"3"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n\n"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"I"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" have"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" all"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" required"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" parameters"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" for"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" both"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" functions"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":","}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" so"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" I"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" can"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" proceed"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" with"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" function"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" calls"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"\n"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"I"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"'ll"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" add"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" and"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" multiply"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" the"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" numbers"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" "}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"2"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" and"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" "}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"3"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" for"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" you"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":".\n"}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_4be9c6251abb4f3fbc1956bd","index":0,"type":"function","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"}}]}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_29207bee5b434b86830450d2","index":1,"type":"function","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"}}]}}]}
+
+ data: {"id":"20251111175650c48a4928f3614935","created":1762855010,"model":"glm-4.5","choices":[{"index":0,"finish_reason":"tool_calls","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":282,"completion_tokens":145,"total_tokens":427,"prompt_tokens_details":{"cached_tokens":258}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream;charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 692.625208ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1691
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"\nI''ll add and multiply the numbers 2 and 3 for you.\n","tool_calls":[{"id":"call_4be9c6251abb4f3fbc1956bd","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"call_29207bee5b434b86830450d2","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant","reasoning_content":"\nThe user wants me to both add and multiply the numbers 2 and 3. I need to use both the add and multiply functions with these parameters.\n\nFor the add function:\n- a: 2\n- b: 3\n\nFor the multiply function:\n- a: 2 \n- b: 3\n\nI have all the required parameters for both functions, so I can proceed with the function calls."},{"content":"5","tool_call_id":"call_4be9c6251abb4f3fbc1956bd","role":"tool"},{"content":"6","tool_call_id":"call_29207bee5b434b86830450d2","role":"tool"}],"model":"glm-4.5","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"The"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" results"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" are"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":":\n"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Adding"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"2"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" and"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"3"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" gives"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"5"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Multip"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"lying"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"2"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" and"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"3"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" gives"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"6"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n\n"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"I"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" should"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" present"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" both"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" results"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" clearly"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" to"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" user"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"\n"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"The"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" results"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" are"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":":\n"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"-"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" **"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"Add"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"ition"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"**:"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" "}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"2"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" +"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" "}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"3"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" ="}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" "}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"5"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"\n"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"-"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" **"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"Multip"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"lication"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"**:"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" "}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"2"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" Ć"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" "}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"3"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" ="}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" "}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"6"}}]}
+
+ data: {"id":"2025111117565556744eb818464fc9","created":1762855015,"model":"glm-4.5","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":440,"completion_tokens":73,"total_tokens":513,"prompt_tokens_details":{"cached_tokens":258}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream;charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 728.965833ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/simple.yaml
new file mode 100644
index 000000000..1539c15e4
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 157
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"glm-4.5","max_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"choices":[{"finish_reason":"stop","index":0,"message":{"content":"OlĆ”!","reasoning_content":"\nThe user is asking me to say \"hi\" in Portuguese. I''ll provide the Portuguese greeting for \"hi\" or \"hello\".\n\nIn Portuguese, \"hi\" or \"hello\" is typically translated as \"OlĆ”\". This is the common greeting used in both Brazilian and European Portuguese.\n\nI''ll respond with this greeting.","role":"assistant"}}],"created":1762854981,"id":"2025111117561942405e9f6eb547c7","model":"glm-4.5","request_id":"2025111117561942405e9f6eb547c7","usage":{"completion_tokens":72,"prompt_tokens":16,"prompt_tokens_details":{"cached_tokens":7},"total_tokens":88}}'
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 4.974643125s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/simple_streaming.yaml
new file mode 100644
index 000000000..5f8b18602
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/simple_streaming.yaml
@@ -0,0 +1,320 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 211
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"glm-4.5","max_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"The"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" person"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" is"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" asking"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" me"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" to"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" say"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"hi"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" in"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Portuguese"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" In"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Portuguese"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":","}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"hi"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" or"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"hello"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" is"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" typically"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" translated"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" as"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"Ol"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"Ć”"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" or"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"Oi"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\"."}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Both"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" are"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" common"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" greetings"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" in"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Portuguese"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"-speaking"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" countries"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":".\n\n"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"Ol"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"Ć”"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" is"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" a"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" bit"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" more"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" formal"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":","}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" while"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"Oi"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" is"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" more"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" informal"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" and"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" casual"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Since"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" request"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" is"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" just"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" to"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" say"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"hi"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\","}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" either"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" would"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" be"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" appropriate"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" I"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"'ll"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" provide"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" both"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" options"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" with"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" a"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" brief"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" explanation"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" of"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" their"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" usage"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"Hi"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" in"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" Portuguese"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" is"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" \""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"Ol"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"Ć”"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"\""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" or"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" \""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"Oi"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"\"."}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" \n\n"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"\""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"Ol"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"Ć”"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"\""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" is"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" a"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" standard"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" greeting"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" that"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" can"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" be"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" used"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" in"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" both"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" formal"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" and"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" informal"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" situations"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":","}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" while"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" \""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"Oi"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"\""}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" is"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" more"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" casual"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" and"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" commonly"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" used"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" among"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" friends"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" and"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" in"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" informal"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" settings"}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"."}}]}
+
+ data: {"id":"20251111175621ea00b15bd30046c2","created":1762854981,"model":"glm-4.5","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":16,"completion_tokens":145,"total_tokens":161,"prompt_tokens_details":{"cached_tokens":6}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream;charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 3.570999666s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/tool.yaml
new file mode 100644
index 000000000..b1869d5d5
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 449
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"glm-4.5","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"choices":[{"finish_reason":"tool_calls","index":0,"message":{"content":"\n","reasoning_content":"\nThe user is asking for the weather in Florence, Italy. I have access to a weather function that takes a location parameter. The user has specified \"Florence, Italy\" as the location. I should use this exact value for the location parameter.","role":"assistant","tool_calls":[{"function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"id":"call_-8170221349237369383","index":0,"type":"function"}]}}],"created":1762854991,"id":"20251111175629f43492c8ddc74b40","model":"glm-4.5","request_id":"20251111175629f43492c8ddc74b40","usage":{"completion_tokens":70,"prompt_tokens":179,"prompt_tokens_details":{"cached_tokens":44},"total_tokens":249}}'
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 2.204044625s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 973
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"\n","tool_calls":[{"id":"call_-8170221349237369383","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_content":"\nThe user is asking for the weather in Florence, Italy. I have access to a weather function that takes a location parameter. The user has specified \"Florence, Italy\" as the location. I should use this exact value for the location parameter."},{"content":"40 C","tool_call_id":"call_-8170221349237369383","role":"tool"}],"model":"glm-4.5","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"choices":[{"finish_reason":"stop","index":0,"message":{"content":"\nThe weather in Florence, Italy is currently 40°C (104°F). That''s quite hot! Make sure to stay hydrated and seek shade if you''re visiting or in the area.","reasoning_content":"\nThe weather function returned that the temperature in Florence, Italy is 40°C. This is quite hot! I should provide this information to the user in a helpful way.","role":"assistant"}}],"created":1762854995,"id":"20251111175631a3e10345eaf44b75","model":"glm-4.5","request_id":"20251111175631a3e10345eaf44b75","usage":{"completion_tokens":76,"prompt_tokens":257,"prompt_tokens_details":{"cached_tokens":43},"total_tokens":333}}'
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 4.128735209s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/tool_streaming.yaml
new file mode 100644
index 000000000..dd652f3c6
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleCommon/zai-glm-4.5/tool_streaming.yaml
@@ -0,0 +1,359 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 503
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"glm-4.5","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"The"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" user"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" is"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" asking"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" for"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" weather"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" in"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Florence"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":","}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Italy"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" I"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" need"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" to"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" use"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" weather"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" function"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" with"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" location"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" parameter"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" The"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" user"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" specified"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"Flo"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"rence"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":","}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"Italy"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\""}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" so"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" I"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" should"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" use"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" that"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" exact"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" string"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" for"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" location"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" parameter"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"\n"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"I"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"'ll"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" check"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" the"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" weather"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" in"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" Florence"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":","}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" Italy"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" for"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" you"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":".\n"}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_6bc2e48a34f34e80995b40d2","index":0,"type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence,Italy\"}"}}]}}]}
+
+ data: {"id":"202511111756356bb63041b022431d","created":1762854995,"model":"glm-4.5","choices":[{"index":0,"finish_reason":"tool_calls","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":179,"completion_tokens":77,"total_tokens":256,"prompt_tokens_details":{"cached_tokens":178}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream;charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.132874458s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1064
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"\nI''ll check the weather in Florence, Italy for you.\n","tool_calls":[{"id":"call_6bc2e48a34f34e80995b40d2","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_content":"\nThe user is asking for the weather in Florence, Italy. I need to use the weather function with the location parameter. The user specified \"Florence,Italy\" so I should use that exact string for the location parameter."},{"content":"40 C","tool_call_id":"call_6bc2e48a34f34e80995b40d2","role":"tool"}],"model":"glm-4.5","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"The"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" weather"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" function"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" returned"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" a"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" temperature"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" of"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"40"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"°C"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" for"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Florence"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":","}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Italy"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" This"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" is"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" quite"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" hot"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"!"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" I"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" should"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" provide"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" this"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" information"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" to"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" user"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" in"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" a"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" clear"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" and"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" helpful"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" way"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"\n"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"The"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" current"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" weather"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" in"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" Florence"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":","}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" Italy"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" is"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" "}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"40"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"°C"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" ("}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"104"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"°F"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":")."}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" That"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"'s"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" quite"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" hot"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"!"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" It"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"'s"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" a"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" very"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" warm"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" day"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" there"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":","}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" so"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" if"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" you"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"'re"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" planning"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" to"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" visit"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":","}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" make"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" sure"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" to"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" stay"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" hydrated"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" and"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" protect"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" yourself"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" from"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" the"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" sun"}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"."}}]}
+
+ data: {"id":"2025111117563873287e56fd174f98","created":1762854998,"model":"glm-4.5","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":264,"completion_tokens":88,"total_tokens":352,"prompt_tokens_details":{"cached_tokens":194}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream;charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 630.944542ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/llama-cpp-gpt-oss/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/llama-cpp-gpt-oss/thinking-streaming.yaml
new file mode 100644
index 000000000..422f26c5d
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/llama-cpp-gpt-oss/thinking-streaming.yaml
@@ -0,0 +1,157 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 523
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"openai/gpt-oss-20b","reasoning_effort":"high","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: http://localhost:8080/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ transfer_encoding:
+ - chunked
+ content_length: -1
+ body: |+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"role":"assistant","content":null}}],"created":1762855742,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"We"}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" need"}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" to"}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" call"}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" function"}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" '"}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"weather"}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"'"}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" with"}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" location"}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" \""}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"Flor"}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"ence"}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":","}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":" Italy"}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"reasoning_content":"\"."}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"tool_calls":[{"index":0,"id":"1wNpqrejg1FCTjf6xq8JRCGKgWZO74AL","type":"function","function":{"name":"weather","arguments":"{\""}}]}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"location"}}]}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Flor"}}]}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"ence"}}]}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":","}}]}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" Italy"}}]}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"}"}}]}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":"tool_calls","index":0,"delta":{}}],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[],"created":1762855743,"id":"chatcmpl-dNaHXNvtiMumXqXykdu8VPuqCSZoLY4U","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk","usage":{"completion_tokens":42,"prompt_tokens":139,"total_tokens":181},"timings":{"cache_n":138,"prompt_n":1,"prompt_ms":9.198,"prompt_per_token_ms":9.198,"prompt_per_second":108.71928680147857,"predicted_n":42,"predicted_ms":344.633,"predicted_per_token_ms":8.205547619047618,"predicted_per_second":121.86877054721981}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 980.667µs
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 873
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"1wNpqrejg1FCTjf6xq8JRCGKgWZO74AL","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_content":"We need to call function ''weather'' with location \"Florence, Italy\"."},{"content":"40 C","tool_call_id":"1wNpqrejg1FCTjf6xq8JRCGKgWZO74AL","role":"tool"}],"model":"openai/gpt-oss-20b","reasoning_effort":"high","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: http://localhost:8080/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ transfer_encoding:
+ - chunked
+ content_length: -1
+ body: |+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"role":"assistant","content":null}}],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":"The"}}],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":" current"}}],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":" weather"}}],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":" in"}}],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":" Florence"}}],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":","}}],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":" Italy"}}],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":" is"}}],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":" **"}}],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":"40"}}],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":"āÆ"}}],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":"°C"}}],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":"**"}}],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":null,"index":0,"delta":{"content":"."}}],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[{"finish_reason":"stop","index":0,"delta":{}}],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk"}
+
+ data: {"choices":[],"created":1762855743,"id":"chatcmpl-KbAer6ddvMjzAfTSDzyLr2XLW1rjunAq","model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion.chunk","usage":{"completion_tokens":18,"prompt_tokens":197,"total_tokens":215},"timings":{"cache_n":161,"prompt_n":36,"prompt_ms":79.751,"prompt_per_token_ms":2.2153055555555556,"prompt_per_second":451.40499805645067,"predicted_n":18,"predicted_ms":139.164,"predicted_per_token_ms":7.731333333333333,"predicted_per_second":129.34379580926102}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.833375ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/llama-cpp-gpt-oss/thinking.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/llama-cpp-gpt-oss/thinking.yaml
new file mode 100644
index 000000000..b979188f7
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/llama-cpp-gpt-oss/thinking.yaml
@@ -0,0 +1,61 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 469
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"openai/gpt-oss-20b","reasoning_effort":"high","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: http://localhost:8080/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 887
+ body: '{"choices":[{"finish_reason":"tool_calls","index":0,"message":{"role":"assistant","reasoning_content":"The user asks: \"What''s the weather in Florence, Italy?\" We can use the weather function. So call the function.","content":null,"tool_calls":[{"type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence, Italy\"}"},"id":"fdRvrwCxXKWGpydIdV3kNaiuirhnhEoL"}]}}],"created":1762855742,"model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion","usage":{"completion_tokens":51,"prompt_tokens":139,"total_tokens":190},"id":"chatcmpl-taknL1RlYNQ4ybq3l7O6u7Th97XVLXui","timings":{"cache_n":134,"prompt_n":5,"prompt_ms":49.294,"prompt_per_token_ms":9.858799999999999,"prompt_per_second":101.43222298859902,"predicted_n":51,"predicted_ms":428.45,"predicted_per_token_ms":8.400980392156862,"predicted_per_second":119.03372622242969}}'
+ headers:
+ Content-Type:
+ - application/json; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 481.413666ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 862
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"fdRvrwCxXKWGpydIdV3kNaiuirhnhEoL","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_content":"The user asks: \"What''s the weather in Florence, Italy?\" We can use the weather function. So call the function."},{"content":"40 C","tool_call_id":"fdRvrwCxXKWGpydIdV3kNaiuirhnhEoL","role":"tool"}],"model":"openai/gpt-oss-20b","reasoning_effort":"high","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: http://localhost:8080/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 821
+ body: '{"choices":[{"finish_reason":"stop","index":0,"message":{"role":"assistant","content":"Hereās the current weather in Florence, Italy:\n\n- **Temperature:** 40āÆĀ°C \n- **Conditions:** Sunny with light wind \n\nEnjoy your day! (If you need more detailsāhumidity, wind speed, forecast, etc.ājust let me know.)"}}],"created":1762855742,"model":"openai/gpt-oss-20b","system_fingerprint":"b7010-c27efd2bd","object":"chat.completion","usage":{"completion_tokens":57,"prompt_tokens":206,"total_tokens":263},"id":"chatcmpl-cHcde6wDsUL9BxFHGP9m6nEMWNXzZR1I","timings":{"cache_n":170,"prompt_n":36,"prompt_ms":79.333,"prompt_per_token_ms":2.2036944444444444,"prompt_per_second":453.7834192580641,"predicted_n":57,"predicted_ms":476.185,"predicted_per_token_ms":8.354122807017545,"predicted_per_second":119.70137656583051}}'
+ headers:
+ Content-Type:
+ - application/json; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 557.318541ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/xai-grok-3-mini/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/xai-grok-3-mini/thinking-streaming.yaml
new file mode 100644
index 000000000..c0275256b
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/xai-grok-3-mini/thinking-streaming.yaml
@@ -0,0 +1,1229 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 516
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"grok-3-mini","reasoning_effort":"high","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"First","role":"assistant"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" user"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" is"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" asking"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" for"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" weather"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" in"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" Florence"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" Italy"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"."}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" have"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" an"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" available"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" called"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"weather"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" that"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" can"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" get"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" weather"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" information"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" for"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" a"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" location"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":".\n\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"The"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" description"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" is"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":":"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"Get"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" weather"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" information"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" for"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" a"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" location"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\"."}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" The"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" parameters"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" require"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" a"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"location"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" which"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" is"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" a"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" string"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" describing"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" city"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":".\n\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"In"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" this"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" query"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" user"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" has"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" provided"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"Florence"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" Italy"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\"."}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" This"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" clearly"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" specifies"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" city"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" and"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" country"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" so"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" location"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" is"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" infer"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"able"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" as"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"Florence"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" Italy"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\"."}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" don't"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" need"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" to"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" ask"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" for"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" more"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" clarification"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":".\n\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"The"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855027,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" should"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" be"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" in"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" JSON"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" format"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" within"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" <"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"_call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":">"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"_call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":">"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" tags"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"."}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" The"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" format"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" is"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":":"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" <"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"_call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":">{\""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"action"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\":"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"_name"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"action"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"_input"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\":"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" {\""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"parameter"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\":"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"argument"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"}}"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"_call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":">\n\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"For"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" this"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" action"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" is"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"weather"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" and"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" action"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"_input"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" should"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" have"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" parameter"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"location"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" with"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" value"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"Florence"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" Italy"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\".\n\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"I"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" should"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" not"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" provide"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" any"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" additional"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" response"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" outside"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" of"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" if"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I'm"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" deciding"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" to"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" a"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" as"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" per"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" instructions"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"."}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" The"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" instructions"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" say"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":":"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"Keep"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" your"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" response"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" to"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" user"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" clear"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":";"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" please"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" do"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" not"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" make"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" your"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" response"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" verbose"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"!\""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" So"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" should"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" just"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" make"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":".\n\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"This"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" seems"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" like"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" a"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" direct"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" match"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" for"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" available"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" and"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855028,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" all"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" required"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" parameters"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" are"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" provided"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"."}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" So"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" should"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":".\n\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"Final"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" decision"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":":"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" Trigger"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" for"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" weather"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" with"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" location"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"Florence"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" Italy"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\"."}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_91894226","function":{"name":"weather","arguments":"{\"location\":\"Florence, Italy\"}"},"index":0,"type":"function"}]}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"b0c242a8-b68d-f435-3f59-b35f8a09195a","object":"chat.completion.chunk","created":1762855029,"model":"grok-3-mini-high","choices":[],"usage":{"prompt_tokens":288,"completion_tokens":27,"total_tokens":588,"prompt_tokens_details":{"text_tokens":288,"audio_tokens":0,"image_tokens":0,"cached_tokens":287},"completion_tokens_details":{"reasoning_tokens":273,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 196.291541ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2177
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"call_91894226","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_content":"First, the user is asking for the weather in Florence, Italy. I have an available function called \"weather\" that can get weather information for a location.\n\nThe function description is: \"Get weather information for a location\". The parameters require a \"location\" which is a string describing the city.\n\nIn this query, the user has provided \"Florence, Italy\". This clearly specifies the city and country, so the location is inferable as \"Florence, Italy\". I don''t need to ask for more clarification.\n\nThe function call should be in JSON format within \u003cfunction_call\u003e\u003c/function_call\u003e tags. The format is: \u003cfunction_call\u003e{\"action\": \"function_name\", \"action_input\": {\"parameter\": \"argument\"}}\u003c/function_call\u003e\n\nFor this, the action is \"weather\", and the action_input should have the parameter \"location\" with the value \"Florence, Italy\".\n\nI should not provide any additional response outside of the function call if I''m deciding to call a function, as per the instructions. The instructions say: \"Keep your response to user clear; please do not make your response verbose!\" So, I should just make the function call.\n\nThis seems like a direct match for the available function, and all required parameters are provided. So, I should call the function.\n\nFinal decision: Trigger the function call for weather with location \"Florence, Italy\"."},{"content":"40 C","tool_call_id":"call_91894226","role":"tool"}],"model":"grok-3-mini","reasoning_effort":"high","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"First","role":"assistant"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" user"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" asked"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":":"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"What's"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" weather"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" in"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" Florence"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" Italy"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"?\""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" This"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" directly"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" matches"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" available"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"weather"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" which"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" requires"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" a"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"location"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" parameter"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":".\n\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"I"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" already"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" called"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" in"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" my"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" previous"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" response"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":":"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" <"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"_call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":">{\""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"action"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\":"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"weather"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"action"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"_input"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\":"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" {\""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"location"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\":"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"Florence"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" Italy"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"}}"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"_call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":">\n\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"Now"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" has"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" been"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" called"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" and"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I'm"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" given"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" a"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" response"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":":"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"Function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":":"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" "}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"40"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" C"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\"."}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" This"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" seems"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" to"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" be"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" output"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" from"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":".\n\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"My"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" role"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" is"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" to"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" be"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" a"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" helpful"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" assistant"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"."}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" After"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" a"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" need"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" to"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" handle"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" response"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" and"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" provide"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" it"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" to"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" user"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855030,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" in"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" a"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" clear"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" non"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"-"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"verbose"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" way"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":".\n\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"The"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" response"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" is"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"40"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" C"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" which"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" assume"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" means"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" "}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"40"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" degrees"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" Celsius"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"."}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" should"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" present"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" this"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" information"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" clearly"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":".\n\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"Since"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" user's"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" query"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" is"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" fully"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" addressed"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" by"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" this"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" don't"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" need"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" to"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" any"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" more"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" functions"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"."}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" should"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" just"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" respond"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" with"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" weather"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" information"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":".\n\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"Response"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" guidelines"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":":\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"-"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" Keep"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" it"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" clear"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" and"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" not"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" verbose"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":".\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"-"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" If"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I'm"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" not"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" calling"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" a"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" don't"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" use"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" <"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"_call"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":">"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" tags"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":".\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"-"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" In"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" this"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" case"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I'm"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" responding"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" to"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" user"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" with"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" the"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" result"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":".\n\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"So"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" should"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" say"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" something"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" like"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":":"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"The"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" weather"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" in"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" Florence"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" Italy"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" is"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" "}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"40"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" degrees"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" Celsius"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":".\"\n\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"The"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" response"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" is"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" just"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" \""}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"40"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855031,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" C"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"\","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" which"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" is"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" informal"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"."}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" should"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" make"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" it"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" user"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"-friendly"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":".\n\n"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"Finally"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" structure"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" my"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" response"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":":"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" Since"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" I'm"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" not"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" calling"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" another"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" function"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" my"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" response"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" should"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" be"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" plain"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":" text"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"reasoning_content":"."}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"content":"The"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"content":" weather"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"content":" in"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"content":" Florence"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"content":","}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"content":" Italy"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"content":" is"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"content":" "}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"content":"40"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"content":"°C"}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{"content":"."}}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: {"id":"4ca6b812-27df-6be3-8428-01d957f2a01c","object":"chat.completion.chunk","created":1762855032,"model":"grok-3-mini-high","choices":[],"usage":{"prompt_tokens":331,"completion_tokens":11,"total_tokens":635,"prompt_tokens_details":{"text_tokens":331,"audio_tokens":0,"image_tokens":0,"cached_tokens":330},"completion_tokens_details":{"reasoning_tokens":293,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_a6fbae1a97"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 170.574ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/xai-grok-3-mini/thinking.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/xai-grok-3-mini/thinking.yaml
new file mode 100644
index 000000000..de62efd6e
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/xai-grok-3-mini/thinking.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 462
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"grok-3-mini","reasoning_effort":"high","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"4d46c468-07c9-43d6-ec35-526a4c35aaa2","object":"chat.completion","created":1762855019,"model":"grok-3-mini-high","choices":[{"index":0,"message":{"role":"assistant","content":"","reasoning_content":"First, the user is asking for the weather in Florence, Italy. I have an available function called \"weather\" that can get weather information for a location. The function requires a \"location\" parameter, which is a string describing the city.\n\nThe location provided in the query is \"Florence, Italy\". This seems clear and matches the required parameter. I can infer that \"Florence, Italy\" is the city name, so I don''t need more information.\n\nThe function description says the location is \"the city\", so passing \"Florence, Italy\" should work as it specifies the city and country, which might help in accuracy.\n\nI should call the function if it can address the query. Here, it directly can, so I need to use the tag in JSON format.\n\nThe format should be: {\"action\": \"weather\", \"action_input\": {\"location\": \"Florence, Italy\"}}\n\nAfter calling the function, I might need to handle the response in subsequent turns, but for now, this is the logical next step.\n\nMy response should not be verbose; keep it clear. Since I''m calling a function, I shouldn''t add extra text unless necessary. The instruction says to use the tag only when deciding to call a function, and not to add other text if not needed. But in this case, since the response is just the function call, I can output that directly.\n\nFinally, confirm: no missing parameters, location is provided. Function matches the query.","tool_calls":[{"id":"call_67567016","function":{"name":"weather","arguments":"{\"location\":\"Florence, Italy\"}"},"type":"function"}],"refusal":null},"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":288,"completion_tokens":27,"total_tokens":621,"prompt_tokens_details":{"text_tokens":288,"audio_tokens":0,"image_tokens":0,"cached_tokens":5},"completion_tokens_details":{"reasoning_tokens":306,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_a6fbae1a97"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.652396875s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2222
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"call_67567016","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_content":"First, the user is asking for the weather in Florence, Italy. I have an available function called \"weather\" that can get weather information for a location. The function requires a \"location\" parameter, which is a string describing the city.\n\nThe location provided in the query is \"Florence, Italy\". This seems clear and matches the required parameter. I can infer that \"Florence, Italy\" is the city name, so I don''t need more information.\n\nThe function description says the location is \"the city\", so passing \"Florence, Italy\" should work as it specifies the city and country, which might help in accuracy.\n\nI should call the function if it can address the query. Here, it directly can, so I need to use the \u003cfunction_call\u003e tag in JSON format.\n\nThe format should be: \u003cfunction_call\u003e{\"action\": \"weather\", \"action_input\": {\"location\": \"Florence, Italy\"}}\u003c/function_call\u003e\n\nAfter calling the function, I might need to handle the response in subsequent turns, but for now, this is the logical next step.\n\nMy response should not be verbose; keep it clear. Since I''m calling a function, I shouldn''t add extra text unless necessary. The instruction says to use the \u003cfunction_call\u003e tag only when deciding to call a function, and not to add other text if not needed. But in this case, since the response is just the function call, I can output that directly.\n\nFinally, confirm: no missing parameters, location is provided. Function matches the query."},{"content":"40 C","tool_call_id":"call_67567016","role":"tool"}],"model":"grok-3-mini","reasoning_effort":"high","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.x.ai/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"8f7e3075-4206-df84-6f7a-689e2b8deb0f","object":"chat.completion","created":1762855023,"model":"grok-3-mini-high","choices":[{"index":0,"message":{"role":"assistant","content":"The weather in Florence, Italy is 40°C.","reasoning_content":"First, the user asked: \"What''s the weather in Florence, Italy?\" This directly matches the available function \"weather\", which retrieves weather information for a location.\n\nThe function call I made was: {\"action\": \"weather\", \"action_input\": {\"location\": \"Florence, Italy\"}}. That was correct because the location is provided and inferable.\n\nNow, the response from the function is: \"40 C\". This seems to be the weather information, likely meaning 40 degrees Celsius.\n\nMy role is to be a helpful assistant. After calling a function, I need to provide a clear response to the user based on the function''s output. The instructions say: \"Keep your response to user clear; please do not make your response verbose!\" So, I should be concise.\n\nThe conversation is multi-turn, but in this case, the function call has been executed, and I have the result. I should now present this information to the user.\n\nThe function output is just \"40 C\", which is minimal. I can infer this means the temperature is 40 degrees Celsius, but I should confirm if there''s more to it. However, the function description is \"Get weather information\", and it returned \"40 C\", so I''ll assume that''s the key information provided.\n\nI need to decide if I should call another function or respond. The user''s request is fulfilled with this weather information, so no need for further function calls.\n\nResponse structure: I should not use tags unless I''m calling a function. Now, I''m responding with the result.\n\nClear and concise response: \"The weather in Florence, Italy is 40 degrees Celsius.\"\n\nTo make it even better, I could say: \"The current weather in Florence, Italy is 40°C.\"\n\nBut the function output is \"40 C\", so I''ll stick close to that.\n\nFinally, ensure I''m not verbose.","refusal":null},"finish_reason":"stop"}],"usage":{"prompt_tokens":331,"completion_tokens":11,"total_tokens":722,"prompt_tokens_details":{"text_tokens":331,"audio_tokens":0,"image_tokens":0,"cached_tokens":283},"completion_tokens_details":{"reasoning_tokens":380,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"num_sources_used":0},"system_fingerprint":"fp_a6fbae1a97"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.91244875s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/zai-glm-4.5/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/zai-glm-4.5/thinking-streaming.yaml
new file mode 100644
index 000000000..44254cedf
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/zai-glm-4.5/thinking-streaming.yaml
@@ -0,0 +1,389 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 512
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"glm-4.5","reasoning_effort":"high","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"The"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" user"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" is"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" asking"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" for"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" weather"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" information"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" for"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Florence"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":","}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Italy"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" I"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" have"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" access"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" to"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" a"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" weather"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" function"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" that"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" takes"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" a"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" location"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" parameter"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" The"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" user"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" has"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" specified"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"Flo"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"rence"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":","}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Italy"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\""}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" as"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" location"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":","}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" so"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" I"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" have"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" all"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" required"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" parameters"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" to"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" make"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" function"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" call"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"\n"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"I"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"'ll"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" check"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" the"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" weather"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" in"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" Florence"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":","}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" Italy"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" for"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" you"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":".\n"}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"delta":{"tool_calls":[{"id":"call_c31d9089eb114d168d3264ff","index":0,"type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence, Italy\"}"}}]}}]}
+
+ data: {"id":"202511111757251676844c980648b3","created":1762855045,"model":"glm-4.5","choices":[{"index":0,"finish_reason":"tool_calls","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":179,"completion_tokens":84,"total_tokens":263,"prompt_tokens_details":{"cached_tokens":178}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream;charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.438553125s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1113
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"content":"\nI''ll check the weather in Florence, Italy for you.\n","tool_calls":[{"id":"call_c31d9089eb114d168d3264ff","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_content":"\nThe user is asking for weather information for Florence, Italy. I have access to a weather function that takes a location parameter. The user has specified \"Florence, Italy\" as the location, so I have all the required parameters to make the function call."},{"content":"40 C","tool_call_id":"call_c31d9089eb114d168d3264ff","role":"tool"}],"model":"glm-4.5","reasoning_effort":"high","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":"\n"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"The"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" weather"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" function"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" returned"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" \""}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"40"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" C"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"\""}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" for"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Florence"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":","}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Italy"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" This"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" indicates"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" current"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" temperature"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" is"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":" "}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"40"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" degrees"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" Celsius"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":","}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" which"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" is"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" quite"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" hot"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" I"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" should"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" provide"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" this"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" information"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" to"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" the"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" user"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" in"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" a"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" clear"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" and"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" helpful"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":" way"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"."}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"\n"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"The"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" current"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" weather"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" in"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" Florence"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":","}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" Italy"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" is"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" "}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"40"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"°C"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" ("}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"104"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"°F"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":")."}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" That"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"'s"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" quite"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" hot"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"!"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" It"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"'s"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" a"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" very"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" warm"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" day"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":","}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" so"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" if"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" you"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"'re"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" planning"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" to"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" be"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" outdoors"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":","}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" make"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" sure"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" to"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" stay"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" hydrated"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" and"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" seek"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" shade"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" when"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":" possible"}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"delta":{"role":"assistant","content":"."}}]}
+
+ data: {"id":"202511111757299016f9976fc249dd","created":1762855049,"model":"glm-4.5","choices":[{"index":0,"finish_reason":"stop","delta":{"role":"assistant","content":""}}],"usage":{"prompt_tokens":271,"completion_tokens":96,"total_tokens":367,"prompt_tokens_details":{"cached_tokens":262}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream;charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 701.355917ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/zai-glm-4.5/thinking.yaml b/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/zai-glm-4.5/thinking.yaml
new file mode 100644
index 000000000..a0a68f965
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAICompatibleThinking/zai-glm-4.5/thinking.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 458
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"glm-4.5","reasoning_effort":"high","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"choices":[{"finish_reason":"tool_calls","index":0,"message":{"content":"\nI''ll check the weather in Florence, Italy for you.\n","reasoning_content":"\nThe user is asking for the weather in Florence, Italy. I need to use the weather function to get this information. The function requires a \"location\" parameter, and the user has specified \"Florence, Italy\" as the location. I should use this exact value for the location parameter.","role":"assistant","tool_calls":[{"function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"id":"call_-8167683298435521960","index":0,"type":"function"}]}}],"created":1762855036,"id":"20251111175712e9c3abb6e9ff40e7","model":"glm-4.5","request_id":"20251111175712e9c3abb6e9ff40e7","usage":{"completion_tokens":91,"prompt_tokens":179,"prompt_tokens_details":{"cached_tokens":44},"total_tokens":270}}'
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 4.539574875s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1078
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"content":"\nI''ll check the weather in Florence, Italy for you.\n","tool_calls":[{"id":"call_-8167683298435521960","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_content":"\nThe user is asking for the weather in Florence, Italy. I need to use the weather function to get this information. The function requires a \"location\" parameter, and the user has specified \"Florence, Italy\" as the location. I should use this exact value for the location parameter."},{"content":"40 C","tool_call_id":"call_-8167683298435521960","role":"tool"}],"model":"glm-4.5","reasoning_effort":"high","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.z.ai/api/coding/paas/v4/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"choices":[{"finish_reason":"stop","index":0,"message":{"content":"\nThe current weather in Florence, Italy is 40°C (104°F). That''s quite hot! Make sure to stay hydrated and seek shade if you''re out and about.","reasoning_content":"\nThe weather function returned \"40 C\" for Florence, Italy. This indicates it''s quite hot - 40 degrees Celsius. I should provide this information to the user in a clear and helpful way.","role":"assistant"}}],"created":1762855045,"id":"20251111175717dfeae12b868f40ed","model":"glm-4.5","request_id":"20251111175717dfeae12b868f40ed","usage":{"completion_tokens":80,"prompt_tokens":278,"prompt_tokens_details":{"cached_tokens":176},"total_tokens":358}}'
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 8.759282417s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o-mini/complex_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o-mini/complex_object.yaml
new file mode 100644
index 000000000..9470db3d9
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o-mini/complex_object.yaml
@@ -0,0 +1,69 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 968
+ host: ""
+ body: '{"messages":[{"content":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","role":"user"}],"model":"gpt-4o-mini","max_tokens":4000,"response_format":{"json_schema":{"name":"Book","strict":true,"description":"A book with title, author, genres, and publication year","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"}},"type":"json_schema"}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CZkh7y0v50HiK3bHkckDQM27mAxaF",
+ "object": "chat.completion",
+ "created": 1762637009,
+ "model": "gpt-4o-mini-2024-07-18",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\",\"Epic\",\"High Fantasy\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}",
+ "refusal": null,
+ "annotations": []
+ },
+ "logprobs": null,
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 160,
+ "completion_tokens": 43,
+ "total_tokens": 203,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 0,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": "fp_560af6e559"
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.814804666s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o-mini/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o-mini/complex_object_streaming.yaml
new file mode 100644
index 000000000..b3f826684
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o-mini/complex_object_streaming.yaml
@@ -0,0 +1,126 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1022
+ host: ""
+ body: '{"messages":[{"content":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","role":"user"}],"model":"gpt-4o-mini","max_tokens":4000,"stream_options":{"include_usage":true},"response_format":{"json_schema":{"name":"Book","strict":true,"description":"A book with title, author, genres, and publication year","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"}},"type":"json_schema"},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"EoocpAT2f"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"{\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"4WcRrCy6"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"author"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"c9snD"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\":{\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"cfO71"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"name"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"R0natd4"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\":\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"TfZHov"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"J"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"o1EOEur9HR"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":".R"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"HoTfqDfrp"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":".R"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"6Zgemp56q"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Lu4Li3pC49"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" Tolkien"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ubO"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\",\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"KEepu5"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"national"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"A2p"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"ity"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"xPvO5yWm"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\":\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"EbLjkP"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"British"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"BxsD"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\"}"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"DLGVoo4R"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":",\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"hnXwwj8X"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"genres"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"gEVWT"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\":[\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"XJ409"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"Fantasy"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"eeqV"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\",\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"PI6dT4"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"Adventure"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"VE"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\",\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"CHOoeY"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"Epic"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"GNkrW3W"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\",\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"96yoKZ"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"High"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"3DHitkZ"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" Fantasy"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"12y"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\"],"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"75v0KEB"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"48pugM49v"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"published"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"oe"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"_year"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"mT79gF"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\":"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"4Uj7yFLo"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"195"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Ir9ny27F"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"4"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"HgJ2OAk2Wf"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":",\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"lspW3jd3"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"title"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"C5hYZ3"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\":\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Wa8NAb"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"o4Fx7yhJ"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" Lord"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"cwn0KV"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"eiCgaQSI"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"IdQLy0E"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":" Rings"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"TOcTG"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\"}"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"bKNNB3Vt"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"TVJnC"}
+
+ data: {"id":"chatcmpl-CZkh9fNoyVymRxJhgvRr0eAMdJPdM","object":"chat.completion.chunk","created":1762637011,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[],"usage":{"prompt_tokens":160,"completion_tokens":43,"total_tokens":203,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"tUHwei0G"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 691.543167ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o-mini/simple_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o-mini/simple_object.yaml
new file mode 100644
index 000000000..61c649e80
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o-mini/simple_object.yaml
@@ -0,0 +1,69 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 601
+ host: ""
+ body: '{"messages":[{"content":"Generate information about a person named Alice who is 30 years old and lives in Paris.","role":"user"}],"model":"gpt-4o-mini","max_tokens":4000,"response_format":{"json_schema":{"name":"Person","strict":true,"description":"A person with name, age, and city","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"}},"type":"json_schema"}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CZkh6UpzjVoPIwiP6798RaJh45GaE",
+ "object": "chat.completion",
+ "created": 1762637008,
+ "model": "gpt-4o-mini-2024-07-18",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}",
+ "refusal": null,
+ "annotations": []
+ },
+ "logprobs": null,
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 99,
+ "completion_tokens": 13,
+ "total_tokens": 112,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 0,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": "fp_560af6e559"
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 926.519208ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o-mini/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o-mini/simple_object_streaming.yaml
new file mode 100644
index 000000000..29959253e
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o-mini/simple_object_streaming.yaml
@@ -0,0 +1,66 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 655
+ host: ""
+ body: '{"messages":[{"content":"Generate information about a person named Alice who is 30 years old and lives in Paris.","role":"user"}],"model":"gpt-4o-mini","max_tokens":4000,"stream_options":{"include_usage":true},"response_format":{"json_schema":{"name":"Person","strict":true,"description":"A person with name, age, and city","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"}},"type":"json_schema"},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CZkh6JIHchpBryosw9Q1zBULiOgQP","object":"chat.completion.chunk","created":1762637008,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"FopRVPvq1"}
+
+ data: {"id":"chatcmpl-CZkh6JIHchpBryosw9Q1zBULiOgQP","object":"chat.completion.chunk","created":1762637008,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"{\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"vcH0mk1c"}
+
+ data: {"id":"chatcmpl-CZkh6JIHchpBryosw9Q1zBULiOgQP","object":"chat.completion.chunk","created":1762637008,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"age"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Yp08y6zs"}
+
+ data: {"id":"chatcmpl-CZkh6JIHchpBryosw9Q1zBULiOgQP","object":"chat.completion.chunk","created":1762637008,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\":"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"yEwAOmw5"}
+
+ data: {"id":"chatcmpl-CZkh6JIHchpBryosw9Q1zBULiOgQP","object":"chat.completion.chunk","created":1762637008,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"30"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"PedSD3PYu"}
+
+ data: {"id":"chatcmpl-CZkh6JIHchpBryosw9Q1zBULiOgQP","object":"chat.completion.chunk","created":1762637008,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":",\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"I5M18YOR"}
+
+ data: {"id":"chatcmpl-CZkh6JIHchpBryosw9Q1zBULiOgQP","object":"chat.completion.chunk","created":1762637008,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"city"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"9ReOCb0"}
+
+ data: {"id":"chatcmpl-CZkh6JIHchpBryosw9Q1zBULiOgQP","object":"chat.completion.chunk","created":1762637008,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\":\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"dRYkzy"}
+
+ data: {"id":"chatcmpl-CZkh6JIHchpBryosw9Q1zBULiOgQP","object":"chat.completion.chunk","created":1762637008,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"Paris"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"clnEfR"}
+
+ data: {"id":"chatcmpl-CZkh6JIHchpBryosw9Q1zBULiOgQP","object":"chat.completion.chunk","created":1762637008,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\",\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"y8uwQU"}
+
+ data: {"id":"chatcmpl-CZkh6JIHchpBryosw9Q1zBULiOgQP","object":"chat.completion.chunk","created":1762637008,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"name"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"hoFrRnB"}
+
+ data: {"id":"chatcmpl-CZkh6JIHchpBryosw9Q1zBULiOgQP","object":"chat.completion.chunk","created":1762637008,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\":\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"f2tFLb"}
+
+ data: {"id":"chatcmpl-CZkh6JIHchpBryosw9Q1zBULiOgQP","object":"chat.completion.chunk","created":1762637008,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"Alice"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"MdtNOk"}
+
+ data: {"id":"chatcmpl-CZkh6JIHchpBryosw9Q1zBULiOgQP","object":"chat.completion.chunk","created":1762637008,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{"content":"\"}"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"4NFrFBQr"}
+
+ data: {"id":"chatcmpl-CZkh6JIHchpBryosw9Q1zBULiOgQP","object":"chat.completion.chunk","created":1762637008,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"RyhJI"}
+
+ data: {"id":"chatcmpl-CZkh6JIHchpBryosw9Q1zBULiOgQP","object":"chat.completion.chunk","created":1762637008,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_560af6e559","choices":[],"usage":{"prompt_tokens":99,"completion_tokens":13,"total_tokens":112,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"a9TEmM6E7"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 611.309416ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o/complex_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o/complex_object.yaml
new file mode 100644
index 000000000..000d1ba9a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o/complex_object.yaml
@@ -0,0 +1,69 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 963
+ host: ""
+ body: '{"messages":[{"content":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","role":"user"}],"model":"gpt-4o","max_tokens":4000,"response_format":{"json_schema":{"name":"Book","strict":true,"description":"A book with title, author, genres, and publication year","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"}},"type":"json_schema"}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CZkh4icu3jixl4IcoAjWVF1mV1oYu",
+ "object": "chat.completion",
+ "created": 1762637006,
+ "model": "gpt-4o-2024-08-06",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\",\"Epic\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}",
+ "refusal": null,
+ "annotations": []
+ },
+ "logprobs": null,
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 160,
+ "completion_tokens": 40,
+ "total_tokens": 200,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 0,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": "fp_b1442291a8"
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.01740425s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o/complex_object_streaming.yaml
new file mode 100644
index 000000000..242bd55c4
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o/complex_object_streaming.yaml
@@ -0,0 +1,126 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1017
+ host: ""
+ body: '{"messages":[{"content":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","role":"user"}],"model":"gpt-4o","max_tokens":4000,"stream_options":{"include_usage":true},"response_format":{"json_schema":{"name":"Book","strict":true,"description":"A book with title, author, genres, and publication year","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"}},"type":"json_schema"},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"oRfA4z9DWq7qj8"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"{\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"6zBd5qX7Btxxs"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"author"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"TM0t4Pm61A"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"\":{\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"vGe6G1eVLX"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"name"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"IzcNGOmzos0t"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"\":\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"l7hTuQxFaSd"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"J"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"KUdeHzDFBeGZqrS"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":".R"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"53WRtPIBKf8ppj"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":".R"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"k1Sj1EOhcZYCrc"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"qg5EAndN8z366Rb"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":" Tolkien"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"5FtxI3Pp"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"\",\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"M5dFMIxnYln"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"national"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"KWRPefSc"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"ity"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Am6NFkfoBupq4"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"\":\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"mE6llEgaiEl"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"British"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"NOxOkP0FW"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"\"}"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"dTuuDbNhmHIam"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":",\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"1YF0LTdj65xaU"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"genres"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"sgSIFdyI3Y"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"\":[\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"J7yKvYHrAE"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"Fantasy"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"1bi4UyMpr"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"\",\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"YKmjdjs48hJ"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"Adventure"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"TPD2t4l"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"\",\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"vlNVJvvgk1c"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"Epic"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"w7jUArhKEasV"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"\",\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"5Y8gslzJdue"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"High"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"cOxUUXJCFsCN"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":" Fantasy"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"pvt7toWU"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"\"],"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"X4iUq3xGjfQZ"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"9DWpvWngJkc3QW"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"published"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"x83XGTN"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"_year"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"b0pZYS1Ugrk"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"\":"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"TnUypAqlvMK0t"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"195"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"5q3RZV2IBGwQq"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"4"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"seaiFS3GIkUeF8R"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":",\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"5z7ebiG1wSVfE"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"title"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"t3kq28e6YDC"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"\":\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"27pSWGte8Fs"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"hbcPvP0yuw3gs"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":" Lord"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"w5Nf8vyr8dS"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":" of"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"oEMgc3xOjSI7i"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"QUboXKjGhMgZ"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":" Rings"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"VzpWMn93wL"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{"content":"\"}"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"6SnH1kmGO0pUa"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"KDN8LMYAVx"}
+
+ data: {"id":"chatcmpl-CZkh4dwQrDDuhFHnkTYw9GVO9PVzy","object":"chat.completion.chunk","created":1762637006,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_b1442291a8","choices":[],"usage":{"prompt_tokens":160,"completion_tokens":43,"total_tokens":203,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"GVU4FsyFvtGsL"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 608.567167ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o/simple_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o/simple_object.yaml
new file mode 100644
index 000000000..8f8ca148e
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o/simple_object.yaml
@@ -0,0 +1,69 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 596
+ host: ""
+ body: '{"messages":[{"content":"Generate information about a person named Alice who is 30 years old and lives in Paris.","role":"user"}],"model":"gpt-4o","max_tokens":4000,"response_format":{"json_schema":{"name":"Person","strict":true,"description":"A person with name, age, and city","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"}},"type":"json_schema"}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CZkh2yUHIKUTvXaI7RuJhKssQ3u8J",
+ "object": "chat.completion",
+ "created": 1762637004,
+ "model": "gpt-4o-2024-08-06",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}",
+ "refusal": null,
+ "annotations": []
+ },
+ "logprobs": null,
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 99,
+ "completion_tokens": 13,
+ "total_tokens": 112,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 0,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": "fp_cbf1785567"
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 866.25175ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o/simple_object_streaming.yaml
new file mode 100644
index 000000000..44ace558e
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-4o/simple_object_streaming.yaml
@@ -0,0 +1,66 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 650
+ host: ""
+ body: '{"messages":[{"content":"Generate information about a person named Alice who is 30 years old and lives in Paris.","role":"user"}],"model":"gpt-4o","max_tokens":4000,"stream_options":{"include_usage":true},"response_format":{"json_schema":{"name":"Person","strict":true,"description":"A person with name, age, and city","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"}},"type":"json_schema"},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CZkh26YobsyDr3tfAEylpsGb7mCKf","object":"chat.completion.chunk","created":1762637004,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"Q7EWId38WGszkS"}
+
+ data: {"id":"chatcmpl-CZkh26YobsyDr3tfAEylpsGb7mCKf","object":"chat.completion.chunk","created":1762637004,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"{\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"WDGuponLquJpz"}
+
+ data: {"id":"chatcmpl-CZkh26YobsyDr3tfAEylpsGb7mCKf","object":"chat.completion.chunk","created":1762637004,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"age"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"rCGUFNPg6GmYo"}
+
+ data: {"id":"chatcmpl-CZkh26YobsyDr3tfAEylpsGb7mCKf","object":"chat.completion.chunk","created":1762637004,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"\":"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"wEfLaS45CzBz3"}
+
+ data: {"id":"chatcmpl-CZkh26YobsyDr3tfAEylpsGb7mCKf","object":"chat.completion.chunk","created":1762637004,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"30"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"FXGR1dTIvN4Qp6"}
+
+ data: {"id":"chatcmpl-CZkh26YobsyDr3tfAEylpsGb7mCKf","object":"chat.completion.chunk","created":1762637004,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":",\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"KmEPUsJzFtpi5"}
+
+ data: {"id":"chatcmpl-CZkh26YobsyDr3tfAEylpsGb7mCKf","object":"chat.completion.chunk","created":1762637004,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"city"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"TxOjAiMNR8i2"}
+
+ data: {"id":"chatcmpl-CZkh26YobsyDr3tfAEylpsGb7mCKf","object":"chat.completion.chunk","created":1762637004,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"\":\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ZdagyqxzdDT"}
+
+ data: {"id":"chatcmpl-CZkh26YobsyDr3tfAEylpsGb7mCKf","object":"chat.completion.chunk","created":1762637004,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"Paris"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"7AV1wjObQw9"}
+
+ data: {"id":"chatcmpl-CZkh26YobsyDr3tfAEylpsGb7mCKf","object":"chat.completion.chunk","created":1762637004,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"\",\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ecbr6MtR7cR"}
+
+ data: {"id":"chatcmpl-CZkh26YobsyDr3tfAEylpsGb7mCKf","object":"chat.completion.chunk","created":1762637004,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"name"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"swinVIK7vWIt"}
+
+ data: {"id":"chatcmpl-CZkh26YobsyDr3tfAEylpsGb7mCKf","object":"chat.completion.chunk","created":1762637004,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"\":\""},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"V94lL7Iu9CQ"}
+
+ data: {"id":"chatcmpl-CZkh26YobsyDr3tfAEylpsGb7mCKf","object":"chat.completion.chunk","created":1762637004,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"Alice"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"tegZ0PohAUA"}
+
+ data: {"id":"chatcmpl-CZkh26YobsyDr3tfAEylpsGb7mCKf","object":"chat.completion.chunk","created":1762637004,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{"content":"\"}"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"npvxJxBLlAEZV"}
+
+ data: {"id":"chatcmpl-CZkh26YobsyDr3tfAEylpsGb7mCKf","object":"chat.completion.chunk","created":1762637004,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"gxtfhzu7ZT"}
+
+ data: {"id":"chatcmpl-CZkh26YobsyDr3tfAEylpsGb7mCKf","object":"chat.completion.chunk","created":1762637004,"model":"gpt-4o-2024-08-06","service_tier":"default","system_fingerprint":"fp_cbf1785567","choices":[],"usage":{"prompt_tokens":99,"completion_tokens":13,"total_tokens":112,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"mo9vda7oGi3jDi"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 878.195625ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-5/complex_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-5/complex_object.yaml
new file mode 100644
index 000000000..b23171032
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-5/complex_object.yaml
@@ -0,0 +1,68 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 973
+ host: ""
+ body: '{"messages":[{"content":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","role":"user"}],"model":"gpt-5","max_completion_tokens":4000,"response_format":{"json_schema":{"name":"Book","strict":true,"description":"A book with title, author, genres, and publication year","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"}},"type":"json_schema"}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CZkhdPgupBvka4xhGSEPQHw0QQKRf",
+ "object": "chat.completion",
+ "created": 1762637041,
+ "model": "gpt-5-2025-08-07",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}",
+ "refusal": null,
+ "annotations": []
+ },
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 156,
+ "completion_tokens": 370,
+ "total_tokens": 526,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 320,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": null
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 6.754405583s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-5/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-5/complex_object_streaming.yaml
new file mode 100644
index 000000000..4841a1f0a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-5/complex_object_streaming.yaml
@@ -0,0 +1,126 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1027
+ host: ""
+ body: '{"messages":[{"content":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","role":"user"}],"model":"gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"response_format":{"json_schema":{"name":"Book","strict":true,"description":"A book with title, author, genres, and publication year","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"}},"type":"json_schema"},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"krULCx6FpP"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"{\""},"finish_reason":null}],"usage":null,"obfuscation":"KhkT4ETwl"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"author"},"finish_reason":null}],"usage":null,"obfuscation":"JiqkV9"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":{\""},"finish_reason":null}],"usage":null,"obfuscation":"pLfh4Y"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"name"},"finish_reason":null}],"usage":null,"obfuscation":"O8warfq1"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":\""},"finish_reason":null}],"usage":null,"obfuscation":"fAH5NNx"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"J"},"finish_reason":null}],"usage":null,"obfuscation":"iRAAQPuX204"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".R"},"finish_reason":null}],"usage":null,"obfuscation":"W1AR5b5TWP"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".R"},"finish_reason":null}],"usage":null,"obfuscation":"VTNoKDtQ17"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"finish_reason":null}],"usage":null,"obfuscation":"HKmoGb3IINO"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Tolkien"},"finish_reason":null}],"usage":null,"obfuscation":"p3JU"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\",\""},"finish_reason":null}],"usage":null,"obfuscation":"vcVbCL4"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"national"},"finish_reason":null}],"usage":null,"obfuscation":"R5MO"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"ity"},"finish_reason":null}],"usage":null,"obfuscation":"hnSvtExqQ"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":\""},"finish_reason":null}],"usage":null,"obfuscation":"HyL59KZ"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"British"},"finish_reason":null}],"usage":null,"obfuscation":"ataN0"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\"}"},"finish_reason":null}],"usage":null,"obfuscation":"OPSMNTPak"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":",\""},"finish_reason":null}],"usage":null,"obfuscation":"puUIHCDXD"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"genres"},"finish_reason":null}],"usage":null,"obfuscation":"66V8sV"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":[\""},"finish_reason":null}],"usage":null,"obfuscation":"zz6Bdi"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Fantasy"},"finish_reason":null}],"usage":null,"obfuscation":"TfPQ2"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\",\""},"finish_reason":null}],"usage":null,"obfuscation":"LNWEFWZ"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Adventure"},"finish_reason":null}],"usage":null,"obfuscation":"1vG"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\",\""},"finish_reason":null}],"usage":null,"obfuscation":"gWtPmFa"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"High"},"finish_reason":null}],"usage":null,"obfuscation":"rmqnBBtT"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" fantasy"},"finish_reason":null}],"usage":null,"obfuscation":"UPen"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\",\""},"finish_reason":null}],"usage":null,"obfuscation":"RDuP2zJ"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Epic"},"finish_reason":null}],"usage":null,"obfuscation":"IsesfQsQ"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\"],"},"finish_reason":null}],"usage":null,"obfuscation":"w4JTRvLk"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\""},"finish_reason":null}],"usage":null,"obfuscation":"3w9JKeR72Q"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"published"},"finish_reason":null}],"usage":null,"obfuscation":"CLT"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"_year"},"finish_reason":null}],"usage":null,"obfuscation":"MkfRSfT"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":"},"finish_reason":null}],"usage":null,"obfuscation":"bBQJScoy8"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"195"},"finish_reason":null}],"usage":null,"obfuscation":"YuX5V3Knn"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"4"},"finish_reason":null}],"usage":null,"obfuscation":"d6BGtnexZOj"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":",\""},"finish_reason":null}],"usage":null,"obfuscation":"tN8ZtZwyn"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"title"},"finish_reason":null}],"usage":null,"obfuscation":"60QEmXN"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":\""},"finish_reason":null}],"usage":null,"obfuscation":"hHsvsxZ"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"The"},"finish_reason":null}],"usage":null,"obfuscation":"64Glw8yPR"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Lord"},"finish_reason":null}],"usage":null,"obfuscation":"UryOL9U"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" of"},"finish_reason":null}],"usage":null,"obfuscation":"J9RVBlCzM"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" the"},"finish_reason":null}],"usage":null,"obfuscation":"He1UQSPn"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Rings"},"finish_reason":null}],"usage":null,"obfuscation":"ldqk2U"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\"}"},"finish_reason":null}],"usage":null,"obfuscation":"eC9lA0XOT"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":null,"obfuscation":"BEksRy"}
+
+ data: {"id":"chatcmpl-CZkhj5CiURkaRRWO5hSOaz31x2Gfh","object":"chat.completion.chunk","created":1762637047,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":156,"completion_tokens":695,"total_tokens":851,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":640,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"CpyYGx"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 14.427336208s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-5/simple_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-5/simple_object.yaml
new file mode 100644
index 000000000..02e8100fb
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-5/simple_object.yaml
@@ -0,0 +1,68 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 606
+ host: ""
+ body: '{"messages":[{"content":"Generate information about a person named Alice who is 30 years old and lives in Paris.","role":"user"}],"model":"gpt-5","max_completion_tokens":4000,"response_format":{"json_schema":{"name":"Person","strict":true,"description":"A person with name, age, and city","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"}},"type":"json_schema"}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CZkhB1eWodsLQ6Gs98f4VUjNlzKV6",
+ "object": "chat.completion",
+ "created": 1762637013,
+ "model": "gpt-5-2025-08-07",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}",
+ "refusal": null,
+ "annotations": []
+ },
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 95,
+ "completion_tokens": 793,
+ "total_tokens": 888,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 768,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": null
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 20.674063542s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-5/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-5/simple_object_streaming.yaml
new file mode 100644
index 000000000..9f3cd6ee2
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-gpt-5/simple_object_streaming.yaml
@@ -0,0 +1,66 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 660
+ host: ""
+ body: '{"messages":[{"content":"Generate information about a person named Alice who is 30 years old and lives in Paris.","role":"user"}],"model":"gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"response_format":{"json_schema":{"name":"Person","strict":true,"description":"A person with name, age, and city","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"}},"type":"json_schema"},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CZkhWAnMkiLSCMK7u8Hid2v2V0JKT","object":"chat.completion.chunk","created":1762637034,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"XOkQ64PZpE"}
+
+ data: {"id":"chatcmpl-CZkhWAnMkiLSCMK7u8Hid2v2V0JKT","object":"chat.completion.chunk","created":1762637034,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"{\""},"finish_reason":null}],"usage":null,"obfuscation":"Ni84MpFSw"}
+
+ data: {"id":"chatcmpl-CZkhWAnMkiLSCMK7u8Hid2v2V0JKT","object":"chat.completion.chunk","created":1762637034,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"age"},"finish_reason":null}],"usage":null,"obfuscation":"HWAfWDi80"}
+
+ data: {"id":"chatcmpl-CZkhWAnMkiLSCMK7u8Hid2v2V0JKT","object":"chat.completion.chunk","created":1762637034,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":"},"finish_reason":null}],"usage":null,"obfuscation":"MgEKDfqen"}
+
+ data: {"id":"chatcmpl-CZkhWAnMkiLSCMK7u8Hid2v2V0JKT","object":"chat.completion.chunk","created":1762637034,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"30"},"finish_reason":null}],"usage":null,"obfuscation":"xSUuDmVnPA"}
+
+ data: {"id":"chatcmpl-CZkhWAnMkiLSCMK7u8Hid2v2V0JKT","object":"chat.completion.chunk","created":1762637034,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":",\""},"finish_reason":null}],"usage":null,"obfuscation":"rg02xRX4E"}
+
+ data: {"id":"chatcmpl-CZkhWAnMkiLSCMK7u8Hid2v2V0JKT","object":"chat.completion.chunk","created":1762637034,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"city"},"finish_reason":null}],"usage":null,"obfuscation":"Otwkppxs"}
+
+ data: {"id":"chatcmpl-CZkhWAnMkiLSCMK7u8Hid2v2V0JKT","object":"chat.completion.chunk","created":1762637034,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":\""},"finish_reason":null}],"usage":null,"obfuscation":"WryBuCt"}
+
+ data: {"id":"chatcmpl-CZkhWAnMkiLSCMK7u8Hid2v2V0JKT","object":"chat.completion.chunk","created":1762637034,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Paris"},"finish_reason":null}],"usage":null,"obfuscation":"xHwu9qY"}
+
+ data: {"id":"chatcmpl-CZkhWAnMkiLSCMK7u8Hid2v2V0JKT","object":"chat.completion.chunk","created":1762637034,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\",\""},"finish_reason":null}],"usage":null,"obfuscation":"5fVw4lG"}
+
+ data: {"id":"chatcmpl-CZkhWAnMkiLSCMK7u8Hid2v2V0JKT","object":"chat.completion.chunk","created":1762637034,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"name"},"finish_reason":null}],"usage":null,"obfuscation":"9Ionk7pl"}
+
+ data: {"id":"chatcmpl-CZkhWAnMkiLSCMK7u8Hid2v2V0JKT","object":"chat.completion.chunk","created":1762637034,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":\""},"finish_reason":null}],"usage":null,"obfuscation":"5vKRCJC"}
+
+ data: {"id":"chatcmpl-CZkhWAnMkiLSCMK7u8Hid2v2V0JKT","object":"chat.completion.chunk","created":1762637034,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Alice"},"finish_reason":null}],"usage":null,"obfuscation":"99RRfh5"}
+
+ data: {"id":"chatcmpl-CZkhWAnMkiLSCMK7u8Hid2v2V0JKT","object":"chat.completion.chunk","created":1762637034,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\"}"},"finish_reason":null}],"usage":null,"obfuscation":"mpjzsT6aj"}
+
+ data: {"id":"chatcmpl-CZkhWAnMkiLSCMK7u8Hid2v2V0JKT","object":"chat.completion.chunk","created":1762637034,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":null,"obfuscation":"Y02J6J"}
+
+ data: {"id":"chatcmpl-CZkhWAnMkiLSCMK7u8Hid2v2V0JKT","object":"chat.completion.chunk","created":1762637034,"model":"gpt-5-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":95,"completion_tokens":345,"total_tokens":440,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":320,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"oT4O7bI"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 6.848382125s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-o4-mini/complex_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-o4-mini/complex_object.yaml
new file mode 100644
index 000000000..931a5c902
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-o4-mini/complex_object.yaml
@@ -0,0 +1,68 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 975
+ host: ""
+ body: '{"messages":[{"content":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","role":"user"}],"model":"o4-mini","max_completion_tokens":4000,"response_format":{"json_schema":{"name":"Book","strict":true,"description":"A book with title, author, genres, and publication year","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"}},"type":"json_schema"}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CZki5CYlesaMKCtCSbinnMUnYGvLR",
+ "object": "chat.completion",
+ "created": 1762637069,
+ "model": "o4-mini-2025-04-16",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}",
+ "refusal": null,
+ "annotations": []
+ },
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 156,
+ "completion_tokens": 187,
+ "total_tokens": 343,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 128,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": null
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.853936875s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-o4-mini/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-o4-mini/complex_object_streaming.yaml
new file mode 100644
index 000000000..cc3d4fa1f
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-o4-mini/complex_object_streaming.yaml
@@ -0,0 +1,116 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1029
+ host: ""
+ body: '{"messages":[{"content":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","role":"user"}],"model":"o4-mini","max_completion_tokens":4000,"stream_options":{"include_usage":true},"response_format":{"json_schema":{"name":"Book","strict":true,"description":"A book with title, author, genres, and publication year","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"}},"type":"json_schema"},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"jSbBDCYa"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"{\""},"finish_reason":null}],"usage":null,"obfuscation":"cHy1o6X"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"author"},"finish_reason":null}],"usage":null,"obfuscation":"un7v"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":{\""},"finish_reason":null}],"usage":null,"obfuscation":"adWo"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"name"},"finish_reason":null}],"usage":null,"obfuscation":"So4L3b"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":\""},"finish_reason":null}],"usage":null,"obfuscation":"6JKwj"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"J"},"finish_reason":null}],"usage":null,"obfuscation":"e5dRHQDF4"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".R"},"finish_reason":null}],"usage":null,"obfuscation":"HQo6f6PP"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".R"},"finish_reason":null}],"usage":null,"obfuscation":"IkNadvEi"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"finish_reason":null}],"usage":null,"obfuscation":"0nUhb2S8E"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Tolkien"},"finish_reason":null}],"usage":null,"obfuscation":"an"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\",\""},"finish_reason":null}],"usage":null,"obfuscation":"8UmMX"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"national"},"finish_reason":null}],"usage":null,"obfuscation":"SU"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"ity"},"finish_reason":null}],"usage":null,"obfuscation":"63TqWO3"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":\""},"finish_reason":null}],"usage":null,"obfuscation":"OhRZz"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"English"},"finish_reason":null}],"usage":null,"obfuscation":"ZkD"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\"}"},"finish_reason":null}],"usage":null,"obfuscation":"oBSiY0t"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":",\""},"finish_reason":null}],"usage":null,"obfuscation":"n3bibfa"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"genres"},"finish_reason":null}],"usage":null,"obfuscation":"ky2m"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":[\""},"finish_reason":null}],"usage":null,"obfuscation":"NAkH"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Fantasy"},"finish_reason":null}],"usage":null,"obfuscation":"94h"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\",\""},"finish_reason":null}],"usage":null,"obfuscation":"rDWyL"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Adventure"},"finish_reason":null}],"usage":null,"obfuscation":"8"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\"],"},"finish_reason":null}],"usage":null,"obfuscation":"97y0Sh"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\""},"finish_reason":null}],"usage":null,"obfuscation":"QiMOEGWe"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"published"},"finish_reason":null}],"usage":null,"obfuscation":"R"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"_year"},"finish_reason":null}],"usage":null,"obfuscation":"nxtvG"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":"},"finish_reason":null}],"usage":null,"obfuscation":"lgQawg6"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"195"},"finish_reason":null}],"usage":null,"obfuscation":"ud4baIJ"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"4"},"finish_reason":null}],"usage":null,"obfuscation":"3HNJ4dBuZ"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":",\""},"finish_reason":null}],"usage":null,"obfuscation":"LrhAiTL"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"title"},"finish_reason":null}],"usage":null,"obfuscation":"gbT7W"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":\""},"finish_reason":null}],"usage":null,"obfuscation":"eWNMD"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"The"},"finish_reason":null}],"usage":null,"obfuscation":"nhGuB0j"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Lord"},"finish_reason":null}],"usage":null,"obfuscation":"0TmEt"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" of"},"finish_reason":null}],"usage":null,"obfuscation":"YrulT4e"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" the"},"finish_reason":null}],"usage":null,"obfuscation":"UOZ211"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Rings"},"finish_reason":null}],"usage":null,"obfuscation":"i73I"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\"}"},"finish_reason":null}],"usage":null,"obfuscation":"vQmYZeA"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":null,"obfuscation":"3et1"}
+
+ data: {"id":"chatcmpl-CZki9S4aKtqtM8RUd4qbiX5kpdYck","object":"chat.completion.chunk","created":1762637073,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":156,"completion_tokens":443,"total_tokens":599,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":384,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"xHYN"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 6.243754208s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-o4-mini/simple_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-o4-mini/simple_object.yaml
new file mode 100644
index 000000000..dcc63f15a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-o4-mini/simple_object.yaml
@@ -0,0 +1,68 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 608
+ host: ""
+ body: '{"messages":[{"content":"Generate information about a person named Alice who is 30 years old and lives in Paris.","role":"user"}],"model":"o4-mini","max_completion_tokens":4000,"response_format":{"json_schema":{"name":"Person","strict":true,"description":"A person with name, age, and city","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"}},"type":"json_schema"}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "id": "chatcmpl-CZkhy2Semw4FSy9i59cUlONdYx0mh",
+ "object": "chat.completion",
+ "created": 1762637062,
+ "model": "o4-mini-2025-04-16",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}",
+ "refusal": null,
+ "annotations": []
+ },
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 95,
+ "completion_tokens": 162,
+ "total_tokens": 257,
+ "prompt_tokens_details": {
+ "cached_tokens": 0,
+ "audio_tokens": 0
+ },
+ "completion_tokens_details": {
+ "reasoning_tokens": 128,
+ "audio_tokens": 0,
+ "accepted_prediction_tokens": 0,
+ "rejected_prediction_tokens": 0
+ }
+ },
+ "service_tier": "default",
+ "system_fingerprint": null
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.135977959s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-o4-mini/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-o4-mini/simple_object_streaming.yaml
new file mode 100644
index 000000000..c74c84e39
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIObjectGeneration/openai-o4-mini/simple_object_streaming.yaml
@@ -0,0 +1,66 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 662
+ host: ""
+ body: '{"messages":[{"content":"Generate information about a person named Alice who is 30 years old and lives in Paris.","role":"user"}],"model":"o4-mini","max_completion_tokens":4000,"stream_options":{"include_usage":true},"response_format":{"json_schema":{"name":"Person","strict":true,"description":"A person with name, age, and city","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"}},"type":"json_schema"},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"chatcmpl-CZki1J9qrKifHLYfd83Fec01s4z8D","object":"chat.completion.chunk","created":1762637065,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"1u4UMeKG"}
+
+ data: {"id":"chatcmpl-CZki1J9qrKifHLYfd83Fec01s4z8D","object":"chat.completion.chunk","created":1762637065,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"{\""},"finish_reason":null}],"usage":null,"obfuscation":"Q5UxGax"}
+
+ data: {"id":"chatcmpl-CZki1J9qrKifHLYfd83Fec01s4z8D","object":"chat.completion.chunk","created":1762637065,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"age"},"finish_reason":null}],"usage":null,"obfuscation":"PC0HaNl"}
+
+ data: {"id":"chatcmpl-CZki1J9qrKifHLYfd83Fec01s4z8D","object":"chat.completion.chunk","created":1762637065,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":"},"finish_reason":null}],"usage":null,"obfuscation":"lsI4acg"}
+
+ data: {"id":"chatcmpl-CZki1J9qrKifHLYfd83Fec01s4z8D","object":"chat.completion.chunk","created":1762637065,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"30"},"finish_reason":null}],"usage":null,"obfuscation":"tcdcmfbK"}
+
+ data: {"id":"chatcmpl-CZki1J9qrKifHLYfd83Fec01s4z8D","object":"chat.completion.chunk","created":1762637065,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":",\""},"finish_reason":null}],"usage":null,"obfuscation":"TD1rpZS"}
+
+ data: {"id":"chatcmpl-CZki1J9qrKifHLYfd83Fec01s4z8D","object":"chat.completion.chunk","created":1762637065,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"city"},"finish_reason":null}],"usage":null,"obfuscation":"IaOcwg"}
+
+ data: {"id":"chatcmpl-CZki1J9qrKifHLYfd83Fec01s4z8D","object":"chat.completion.chunk","created":1762637065,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":\""},"finish_reason":null}],"usage":null,"obfuscation":"6cUFm"}
+
+ data: {"id":"chatcmpl-CZki1J9qrKifHLYfd83Fec01s4z8D","object":"chat.completion.chunk","created":1762637065,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Paris"},"finish_reason":null}],"usage":null,"obfuscation":"2yZjs"}
+
+ data: {"id":"chatcmpl-CZki1J9qrKifHLYfd83Fec01s4z8D","object":"chat.completion.chunk","created":1762637065,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\",\""},"finish_reason":null}],"usage":null,"obfuscation":"Q37jl"}
+
+ data: {"id":"chatcmpl-CZki1J9qrKifHLYfd83Fec01s4z8D","object":"chat.completion.chunk","created":1762637065,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"name"},"finish_reason":null}],"usage":null,"obfuscation":"kT7Jci"}
+
+ data: {"id":"chatcmpl-CZki1J9qrKifHLYfd83Fec01s4z8D","object":"chat.completion.chunk","created":1762637065,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":\""},"finish_reason":null}],"usage":null,"obfuscation":"ou5VZ"}
+
+ data: {"id":"chatcmpl-CZki1J9qrKifHLYfd83Fec01s4z8D","object":"chat.completion.chunk","created":1762637065,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Alice"},"finish_reason":null}],"usage":null,"obfuscation":"AMhVx"}
+
+ data: {"id":"chatcmpl-CZki1J9qrKifHLYfd83Fec01s4z8D","object":"chat.completion.chunk","created":1762637065,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\"}"},"finish_reason":null}],"usage":null,"obfuscation":"ZDFb7mY"}
+
+ data: {"id":"chatcmpl-CZki1J9qrKifHLYfd83Fec01s4z8D","object":"chat.completion.chunk","created":1762637065,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":null,"obfuscation":"AQhR"}
+
+ data: {"id":"chatcmpl-CZki1J9qrKifHLYfd83Fec01s4z8D","object":"chat.completion.chunk","created":1762637065,"model":"o4-mini-2025-04-16","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":95,"completion_tokens":290,"total_tokens":385,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":256,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"xEKhD"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 3.874454375s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/multi_tool.yaml
new file mode 100644
index 000000000..6200528a8
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/multi_tool.yaml
@@ -0,0 +1,293 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 839
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":[{"text":"Add and multiply the number 2 and 3","type":"input_text"}],"role":"user"}],"model":"gpt-4o-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers","type":"function"},{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_0e6e91029b6ada300168f237eec6608195ad0152f869ad01dc",
+ "object": "response",
+ "created_at": 1760704494,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-4o-mini-2024-07-18",
+ "output": [
+ {
+ "id": "fc_0e6e91029b6ada300168f237efd70c8195aa55d25207351903",
+ "type": "function_call",
+ "status": "completed",
+ "arguments": "{\"a\":2,\"b\":3}",
+ "call_id": "call_OHopAt0ZeLfG0Th5YYgklQUA",
+ "name": "add"
+ },
+ {
+ "id": "fc_0e6e91029b6ada300168f237f056848195b392f4da0c8c085c",
+ "type": "function_call",
+ "status": "completed",
+ "arguments": "{\"a\":2,\"b\":3}",
+ "call_id": "call_CuDiIyPSC4zAkb7l4cjiEBot",
+ "name": "multiply"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": null,
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Add two numbers",
+ "name": "add",
+ "parameters": {
+ "properties": {
+ "a": {
+ "description": "first number",
+ "type": "integer"
+ },
+ "b": {
+ "description": "second number",
+ "type": "integer"
+ }
+ },
+ "required": [
+ "a",
+ "b"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ },
+ {
+ "type": "function",
+ "description": "Multiply two numbers",
+ "name": "multiply",
+ "parameters": {
+ "properties": {
+ "a": {
+ "description": "first number",
+ "type": "integer"
+ },
+ "b": {
+ "description": "second number",
+ "type": "integer"
+ }
+ },
+ "required": [
+ "a",
+ "b"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 54,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 50,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 104
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.986247916s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1266
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":[{"text":"Add and multiply the number 2 and 3","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"a\\\":2,\\\"b\\\":3}\"","call_id":"call_OHopAt0ZeLfG0Th5YYgklQUA","name":"add","type":"function_call"},{"arguments":"\"{\\\"a\\\":2,\\\"b\\\":3}\"","call_id":"call_CuDiIyPSC4zAkb7l4cjiEBot","name":"multiply","type":"function_call"},{"call_id":"call_OHopAt0ZeLfG0Th5YYgklQUA","output":"5","type":"function_call_output"},{"call_id":"call_CuDiIyPSC4zAkb7l4cjiEBot","output":"6","type":"function_call_output"}],"model":"gpt-4o-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers","type":"function"},{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_0d01b8c6f6fd8fea0168f237f0b9d88192a55dfc495051641f",
+ "object": "response",
+ "created_at": 1760704496,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-4o-mini-2024-07-18",
+ "output": [
+ {
+ "id": "msg_0d01b8c6f6fd8fea0168f237f11b3881929b9577533766ce13",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "The results are as follows:\n\n- Addition of 2 and 3: **5**\n- Multiplication of 2 and 3: **6**"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": null,
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Add two numbers",
+ "name": "add",
+ "parameters": {
+ "properties": {
+ "a": {
+ "description": "first number",
+ "type": "integer"
+ },
+ "b": {
+ "description": "second number",
+ "type": "integer"
+ }
+ },
+ "required": [
+ "a",
+ "b"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ },
+ {
+ "type": "function",
+ "description": "Multiply two numbers",
+ "name": "multiply",
+ "parameters": {
+ "properties": {
+ "a": {
+ "description": "first number",
+ "type": "integer"
+ },
+ "b": {
+ "description": "second number",
+ "type": "integer"
+ }
+ },
+ "required": [
+ "a",
+ "b"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 156,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 33,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 189
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.0980445s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/multi_tool_streaming.yaml
new file mode 100644
index 000000000..08e8b7dd5
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/multi_tool_streaming.yaml
@@ -0,0 +1,232 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 836
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":[{"text":"Add and multiply the number 2 and 3","type":"input_text"}],"role":"user"}],"model":"gpt-4o-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers","type":"function"},{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_00a8e88fa6f940ad0168f237f1dd888193a1ef5c9847dab08c","object":"response","created_at":1760704498,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_00a8e88fa6f940ad0168f237f1dd888193a1ef5c9847dab08c","object":"response","created_at":1760704498,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"fc_00a8e88fa6f940ad0168f237f314c08193b9a1bbcfcac14cf0","type":"function_call","status":"in_progress","arguments":"","call_id":"call_3kTB5GwkneSeSzqRU0vGYPDL","name":"add"}}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":3,"item_id":"fc_00a8e88fa6f940ad0168f237f314c08193b9a1bbcfcac14cf0","output_index":0,"delta":"{","obfuscation":"MYJbzQXS8koAMnE"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":4,"item_id":"fc_00a8e88fa6f940ad0168f237f314c08193b9a1bbcfcac14cf0","output_index":0,"delta":"\"a","obfuscation":"QsLZoZF7HORhVg"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":5,"item_id":"fc_00a8e88fa6f940ad0168f237f314c08193b9a1bbcfcac14cf0","output_index":0,"delta":"\":","obfuscation":"t1wiWnFzF3XGK3"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":6,"item_id":"fc_00a8e88fa6f940ad0168f237f314c08193b9a1bbcfcac14cf0","output_index":0,"delta":"2,","obfuscation":"RGkyrnS7pyZ4Dc"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":7,"item_id":"fc_00a8e88fa6f940ad0168f237f314c08193b9a1bbcfcac14cf0","output_index":0,"delta":"\"b","obfuscation":"EaoxiEhgZ08nqy"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":8,"item_id":"fc_00a8e88fa6f940ad0168f237f314c08193b9a1bbcfcac14cf0","output_index":0,"delta":"\":","obfuscation":"JVvJNSMiELxKzO"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":9,"item_id":"fc_00a8e88fa6f940ad0168f237f314c08193b9a1bbcfcac14cf0","output_index":0,"delta":"3}","obfuscation":"x4XeMEEEMraVP6"}
+
+ event: response.function_call_arguments.done
+ data: {"type":"response.function_call_arguments.done","sequence_number":10,"item_id":"fc_00a8e88fa6f940ad0168f237f314c08193b9a1bbcfcac14cf0","output_index":0,"arguments":"{\"a\":2,\"b\":3}"}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":11,"output_index":0,"item":{"id":"fc_00a8e88fa6f940ad0168f237f314c08193b9a1bbcfcac14cf0","type":"function_call","status":"completed","arguments":"{\"a\":2,\"b\":3}","call_id":"call_3kTB5GwkneSeSzqRU0vGYPDL","name":"add"}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":12,"output_index":1,"item":{"id":"fc_00a8e88fa6f940ad0168f237f36d5481939649569c1b43bad3","type":"function_call","status":"in_progress","arguments":"","call_id":"call_Jt8bB5S9YYfmIi76VQmbBbRU","name":"multiply"}}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":13,"item_id":"fc_00a8e88fa6f940ad0168f237f36d5481939649569c1b43bad3","output_index":1,"delta":"{","obfuscation":"1RSWOvhsqosKvNT"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":14,"item_id":"fc_00a8e88fa6f940ad0168f237f36d5481939649569c1b43bad3","output_index":1,"delta":"\"a","obfuscation":"q5YBU194JPt2K7"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":15,"item_id":"fc_00a8e88fa6f940ad0168f237f36d5481939649569c1b43bad3","output_index":1,"delta":"\":","obfuscation":"0ST7G5t6xpPBbm"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":16,"item_id":"fc_00a8e88fa6f940ad0168f237f36d5481939649569c1b43bad3","output_index":1,"delta":"2,","obfuscation":"fehmIw5XYwhSmd"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":17,"item_id":"fc_00a8e88fa6f940ad0168f237f36d5481939649569c1b43bad3","output_index":1,"delta":"\"b","obfuscation":"aTdnl1XrjAoVfk"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":18,"item_id":"fc_00a8e88fa6f940ad0168f237f36d5481939649569c1b43bad3","output_index":1,"delta":"\":","obfuscation":"MZxsdfhi5quYaN"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":19,"item_id":"fc_00a8e88fa6f940ad0168f237f36d5481939649569c1b43bad3","output_index":1,"delta":"3}","obfuscation":"oo1Zml2PxLLsqt"}
+
+ event: response.function_call_arguments.done
+ data: {"type":"response.function_call_arguments.done","sequence_number":20,"item_id":"fc_00a8e88fa6f940ad0168f237f36d5481939649569c1b43bad3","output_index":1,"arguments":"{\"a\":2,\"b\":3}"}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":21,"output_index":1,"item":{"id":"fc_00a8e88fa6f940ad0168f237f36d5481939649569c1b43bad3","type":"function_call","status":"completed","arguments":"{\"a\":2,\"b\":3}","call_id":"call_Jt8bB5S9YYfmIi76VQmbBbRU","name":"multiply"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":22,"response":{"id":"resp_00a8e88fa6f940ad0168f237f1dd888193a1ef5c9847dab08c","object":"response","created_at":1760704498,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[{"id":"fc_00a8e88fa6f940ad0168f237f314c08193b9a1bbcfcac14cf0","type":"function_call","status":"completed","arguments":"{\"a\":2,\"b\":3}","call_id":"call_3kTB5GwkneSeSzqRU0vGYPDL","name":"add"},{"id":"fc_00a8e88fa6f940ad0168f237f36d5481939649569c1b43bad3","type":"function_call","status":"completed","arguments":"{\"a\":2,\"b\":3}","call_id":"call_Jt8bB5S9YYfmIi76VQmbBbRU","name":"multiply"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":52,"input_tokens_details":{"cached_tokens":0},"output_tokens":50,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":102},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 484.945334ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1263
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":[{"text":"Add and multiply the number 2 and 3","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"a\\\":2,\\\"b\\\":3}\"","call_id":"call_3kTB5GwkneSeSzqRU0vGYPDL","name":"add","type":"function_call"},{"arguments":"\"{\\\"a\\\":2,\\\"b\\\":3}\"","call_id":"call_Jt8bB5S9YYfmIi76VQmbBbRU","name":"multiply","type":"function_call"},{"call_id":"call_3kTB5GwkneSeSzqRU0vGYPDL","output":"5","type":"function_call_output"},{"call_id":"call_Jt8bB5S9YYfmIi76VQmbBbRU","output":"6","type":"function_call_output"}],"model":"gpt-4o-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers","type":"function"},{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0dce58b46fca39020168f237f414988197b9530f9cacc71f05","object":"response","created_at":1760704500,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0dce58b46fca39020168f237f414988197b9530f9cacc71f05","object":"response","created_at":1760704500,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"KXnqGA8frpb3Z"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":" sum","logprobs":[],"obfuscation":"muAcpURnEZNO"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"NiiFQNE8Vbx3m"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"iedCm3V4NG5VwKG"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":"2","logprobs":[],"obfuscation":"DpkpH9aX7QlOgRI"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":" and","logprobs":[],"obfuscation":"JKO99mU6Fzjd"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"DKM0PLMlWtpJ2db"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":"3","logprobs":[],"obfuscation":"mNeixBaCsE7BA3E"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"bVAgqZAo0CgC6"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":" **","logprobs":[],"obfuscation":"jSwrxR8I6VXfC"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":"5","logprobs":[],"obfuscation":"XLGPJZ5j6iFMyJA"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":"**,","logprobs":[],"obfuscation":"t6jjUQXk4bJje"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":" and","logprobs":[],"obfuscation":"lO0lZAk18hmY"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"mWdiBmSqYvRX"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":" product","logprobs":[],"obfuscation":"8JcFiI34"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"TPkzDFwQxJbSv"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"LJlbhe5chuMFaet"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":"2","logprobs":[],"obfuscation":"b0aoUxaTomg3dRS"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":" and","logprobs":[],"obfuscation":"87UGzV4meZ0c"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"DqZaRc0KL1HCaa7"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":"3","logprobs":[],"obfuscation":"2XztAgjOUqo2XhP"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"5R24VMFP7z2bO"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":" **","logprobs":[],"obfuscation":"4h58jpYffdpGo"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":"6","logprobs":[],"obfuscation":"Btim10fw2C3Hmlh"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":"**","logprobs":[],"obfuscation":"OPI3mnY896mA1s"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":29,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"2VzoXZZJZ0dW8MY"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":30,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"text":"The sum of 2 and 3 is **5**, and the product of 2 and 3 is **6**.","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":31,"item_id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"The sum of 2 and 3 is **5**, and the product of 2 and 3 is **6**."}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":32,"output_index":0,"item":{"id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The sum of 2 and 3 is **5**, and the product of 2 and 3 is **6**."}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":33,"response":{"id":"resp_0dce58b46fca39020168f237f414988197b9530f9cacc71f05","object":"response","created_at":1760704500,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[{"id":"msg_0dce58b46fca39020168f237f489188197a1fdc7d8f7aa79f8","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The sum of 2 and 3 is **5**, and the product of 2 and 3 is **6**."}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":152,"input_tokens_details":{"cached_tokens":0},"output_tokens":28,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":180},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 413.404917ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/simple.yaml
new file mode 100644
index 000000000..c520cfc5a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/simple.yaml
@@ -0,0 +1,100 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 210
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"system"},{"content":[{"text":"Say hi in Portuguese","type":"input_text"}],"role":"user"}],"model":"gpt-4o-mini"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_02fb59ed5cb3cadf0168f237e8ce908195baa9463cad5776cb",
+ "object": "response",
+ "created_at": 1760704488,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-4o-mini-2024-07-18",
+ "output": [
+ {
+ "id": "msg_02fb59ed5cb3cadf0168f237e93f388195afee2cc6277cfaa0",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "Oi!"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": null,
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 20,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 3,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 23
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 701.807792ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/simple_streaming.yaml
new file mode 100644
index 000000000..684970281
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/simple_streaming.yaml
@@ -0,0 +1,62 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 224
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"system"},{"content":[{"text":"Say hi in Portuguese","type":"input_text"}],"role":"user"}],"model":"gpt-4o-mini","stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_05eea6934a1b65980168f237e98214819693e879eb9deb3718","object":"response","created_at":1760704489,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_05eea6934a1b65980168f237e98214819693e879eb9deb3718","object":"response","created_at":1760704489,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_05eea6934a1b65980168f237ea15448196bb4186395ed2288d","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_05eea6934a1b65980168f237ea15448196bb4186395ed2288d","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_05eea6934a1b65980168f237ea15448196bb4186395ed2288d","output_index":0,"content_index":0,"delta":"Oi","logprobs":[],"obfuscation":"PLeCwMMZIiZ7tE"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_05eea6934a1b65980168f237ea15448196bb4186395ed2288d","output_index":0,"content_index":0,"delta":"!","logprobs":[],"obfuscation":"VYhGbSW2JCl6w1K"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":6,"item_id":"msg_05eea6934a1b65980168f237ea15448196bb4186395ed2288d","output_index":0,"content_index":0,"text":"Oi!","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":7,"item_id":"msg_05eea6934a1b65980168f237ea15448196bb4186395ed2288d","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"Oi!"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":8,"output_index":0,"item":{"id":"msg_05eea6934a1b65980168f237ea15448196bb4186395ed2288d","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"Oi!"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":9,"response":{"id":"resp_05eea6934a1b65980168f237e98214819693e879eb9deb3718","object":"response","created_at":1760704489,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[{"id":"msg_05eea6934a1b65980168f237ea15448196bb4186395ed2288d","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"Oi!"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":20,"input_tokens_details":{"cached_tokens":0},"output_tokens":3,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":23},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 413.059208ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/tool.yaml
new file mode 100644
index 000000000..ee83f6ab3
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/tool.yaml
@@ -0,0 +1,229 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 489
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"system"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"}],"model":"gpt-4o-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_010f0015da2b88280168f237ea6c18819e8ce2b72d44ac08b4",
+ "object": "response",
+ "created_at": 1760704490,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-4o-mini-2024-07-18",
+ "output": [
+ {
+ "id": "fc_010f0015da2b88280168f237eb2b7c819eae6470cdee55da77",
+ "type": "function_call",
+ "status": "completed",
+ "arguments": "{\"location\":\"Florence, Italy\"}",
+ "call_id": "call_59vzLlFlML0RoHvlJxgWZZ7m",
+ "name": "weather"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": null,
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 58,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 17,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 75
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.0454615s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 724
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"system"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_59vzLlFlML0RoHvlJxgWZZ7m","name":"weather","type":"function_call"},{"call_id":"call_59vzLlFlML0RoHvlJxgWZZ7m","output":"40 C","type":"function_call_output"}],"model":"gpt-4o-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_0de529b5396cb7cc0168f237eb7d9c81a3aca3fef6a9749a5f",
+ "object": "response",
+ "created_at": 1760704491,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-4o-mini-2024-07-18",
+ "output": [
+ {
+ "id": "msg_0de529b5396cb7cc0168f237ebf0ec81a39a23afc61ca30582",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "The current temperature in Florence, Italy, is 40\u00b0C. If you need more details like humidity or forecast, just let me know!"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": null,
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 83,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 30,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 113
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.421569667s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/tool_streaming.yaml
new file mode 100644
index 000000000..13e5d7737
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o-mini/tool_streaming.yaml
@@ -0,0 +1,211 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 503
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"system"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"}],"model":"gpt-4o-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0915a342b22b18d50168f237ece814819fbbac6dc48dd0edb2","object":"response","created_at":1760704492,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0915a342b22b18d50168f237ece814819fbbac6dc48dd0edb2","object":"response","created_at":1760704492,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"fc_0915a342b22b18d50168f237ed7be4819fb7686ac852408033","type":"function_call","status":"in_progress","arguments":"","call_id":"call_ytBD13XK47ACiCTAyn4RZCSb","name":"weather"}}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":3,"item_id":"fc_0915a342b22b18d50168f237ed7be4819fb7686ac852408033","output_index":0,"delta":"{\"","obfuscation":"Hrtnjbqy71fTf2"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":4,"item_id":"fc_0915a342b22b18d50168f237ed7be4819fb7686ac852408033","output_index":0,"delta":"location","obfuscation":"pzYupDDV"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":5,"item_id":"fc_0915a342b22b18d50168f237ed7be4819fb7686ac852408033","output_index":0,"delta":"\":\"","obfuscation":"l8BCOLb4pKgPH"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":6,"item_id":"fc_0915a342b22b18d50168f237ed7be4819fb7686ac852408033","output_index":0,"delta":"Flor","obfuscation":"XuNP9JDMdMXF"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":7,"item_id":"fc_0915a342b22b18d50168f237ed7be4819fb7686ac852408033","output_index":0,"delta":"ence","obfuscation":"TFnsqDERhUnk"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":8,"item_id":"fc_0915a342b22b18d50168f237ed7be4819fb7686ac852408033","output_index":0,"delta":",","obfuscation":"Ot0Lx95tLZ6T2MK"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":9,"item_id":"fc_0915a342b22b18d50168f237ed7be4819fb7686ac852408033","output_index":0,"delta":" Italy","obfuscation":"6x0z1jEIf7"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":10,"item_id":"fc_0915a342b22b18d50168f237ed7be4819fb7686ac852408033","output_index":0,"delta":"\"}","obfuscation":"XxvQGBcCf9Gh8t"}
+
+ event: response.function_call_arguments.done
+ data: {"type":"response.function_call_arguments.done","sequence_number":11,"item_id":"fc_0915a342b22b18d50168f237ed7be4819fb7686ac852408033","output_index":0,"arguments":"{\"location\":\"Florence, Italy\"}"}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":12,"output_index":0,"item":{"id":"fc_0915a342b22b18d50168f237ed7be4819fb7686ac852408033","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence, Italy\"}","call_id":"call_ytBD13XK47ACiCTAyn4RZCSb","name":"weather"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":13,"response":{"id":"resp_0915a342b22b18d50168f237ece814819fbbac6dc48dd0edb2","object":"response","created_at":1760704492,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[{"id":"fc_0915a342b22b18d50168f237ed7be4819fb7686ac852408033","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence, Italy\"}","call_id":"call_ytBD13XK47ACiCTAyn4RZCSb","name":"weather"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":58,"input_tokens_details":{"cached_tokens":0},"output_tokens":17,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":75},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 236.516125ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 738
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"system"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_ytBD13XK47ACiCTAyn4RZCSb","name":"weather","type":"function_call"},{"call_id":"call_ytBD13XK47ACiCTAyn4RZCSb","output":"40 C","type":"function_call_output"}],"model":"gpt-4o-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_03b372deeab9afef0168f237edcaac8195a4aa3d164255738c","object":"response","created_at":1760704493,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_03b372deeab9afef0168f237edcaac8195a4aa3d164255738c","object":"response","created_at":1760704493,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"LbJ0zrf2Xlbtt"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" current","logprobs":[],"obfuscation":"gSB6Ljso"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" temperature","logprobs":[],"obfuscation":"6HSV"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"2olcAesqOKi1y"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" Florence","logprobs":[],"obfuscation":"nbgdzjL"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"YoZssiZgz5zHS6h"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" Italy","logprobs":[],"obfuscation":"02oJoNSkie"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"pez2xfiPiFc29Ho"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"MFk9ejbypODoX"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"6XX7qV3SfkXCP3E"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":"40","logprobs":[],"obfuscation":"staQ8SeYDAvuUZ"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":"°C","logprobs":[],"obfuscation":"jS2kbp5xGRAQKR"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"GhbVrcMoP8Je3IX"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" If","logprobs":[],"obfuscation":"aRk18WTNA45gH"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" you","logprobs":[],"obfuscation":"kbEO7bKGPMTR"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" need","logprobs":[],"obfuscation":"k3UWS3v8OLR"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" more","logprobs":[],"obfuscation":"q3E8iPZa3bR"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" details","logprobs":[],"obfuscation":"4PXIjoSv"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" about","logprobs":[],"obfuscation":"QIjhgtABf3"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"jJELxprdIxCs"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" weather","logprobs":[],"obfuscation":"2uDTEcSy"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" conditions","logprobs":[],"obfuscation":"8xVDS"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"TioHCr0j04ibL6K"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" feel","logprobs":[],"obfuscation":"KW1peE4VWsd"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" free","logprobs":[],"obfuscation":"es0c6QGaBJt"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":29,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" to","logprobs":[],"obfuscation":"aMZakoFmaTLnI"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":30,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":" ask","logprobs":[],"obfuscation":"tcXPkxUY2xuP"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":31,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"delta":"!","logprobs":[],"obfuscation":"WwWEZBAyOpDhWvp"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":32,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"text":"The current temperature in Florence, Italy, is 40°C. If you need more details about the weather conditions, feel free to ask!","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":33,"item_id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"The current temperature in Florence, Italy, is 40°C. If you need more details about the weather conditions, feel free to ask!"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":34,"output_index":0,"item":{"id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current temperature in Florence, Italy, is 40°C. If you need more details about the weather conditions, feel free to ask!"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":35,"response":{"id":"resp_03b372deeab9afef0168f237edcaac8195a4aa3d164255738c","object":"response","created_at":1760704493,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[{"id":"msg_03b372deeab9afef0168f237ee2e0881959296453175fdf7c1","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current temperature in Florence, Italy, is 40°C. If you need more details about the weather conditions, feel free to ask!"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":83,"input_tokens_details":{"cached_tokens":0},"output_tokens":30,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":113},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 394.542125ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/multi_tool.yaml
new file mode 100644
index 000000000..62635da09
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/multi_tool.yaml
@@ -0,0 +1,293 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 834
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":[{"text":"Add and multiply the number 2 and 3","type":"input_text"}],"role":"user"}],"model":"gpt-4o","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers","type":"function"},{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_0e4ad943aeeb6f440168f237e4ba68819d82d960503add3455",
+ "object": "response",
+ "created_at": 1760704484,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-4o-2024-08-06",
+ "output": [
+ {
+ "id": "fc_0e4ad943aeeb6f440168f237e55708819dbb4bacb951338226",
+ "type": "function_call",
+ "status": "completed",
+ "arguments": "{\"a\":2,\"b\":3}",
+ "call_id": "call_fWTsR6VaKuyav2YHicLHxgUu",
+ "name": "add"
+ },
+ {
+ "id": "fc_0e4ad943aeeb6f440168f237e57510819db015d8ff8e768bdb",
+ "type": "function_call",
+ "status": "completed",
+ "arguments": "{\"a\":2,\"b\":3}",
+ "call_id": "call_KLpoIGIQ4rbE8b3AWCUaui6g",
+ "name": "multiply"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": null,
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Add two numbers",
+ "name": "add",
+ "parameters": {
+ "properties": {
+ "a": {
+ "description": "first number",
+ "type": "integer"
+ },
+ "b": {
+ "description": "second number",
+ "type": "integer"
+ }
+ },
+ "required": [
+ "a",
+ "b"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ },
+ {
+ "type": "function",
+ "description": "Multiply two numbers",
+ "name": "multiply",
+ "parameters": {
+ "properties": {
+ "a": {
+ "description": "first number",
+ "type": "integer"
+ },
+ "b": {
+ "description": "second number",
+ "type": "integer"
+ }
+ },
+ "required": [
+ "a",
+ "b"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 54,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 50,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 104
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 991.245209ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1261
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":[{"text":"Add and multiply the number 2 and 3","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"a\\\":2,\\\"b\\\":3}\"","call_id":"call_fWTsR6VaKuyav2YHicLHxgUu","name":"add","type":"function_call"},{"arguments":"\"{\\\"a\\\":2,\\\"b\\\":3}\"","call_id":"call_KLpoIGIQ4rbE8b3AWCUaui6g","name":"multiply","type":"function_call"},{"call_id":"call_fWTsR6VaKuyav2YHicLHxgUu","output":"5","type":"function_call_output"},{"call_id":"call_KLpoIGIQ4rbE8b3AWCUaui6g","output":"6","type":"function_call_output"}],"model":"gpt-4o","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers","type":"function"},{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_03837d599fa2bb470168f237e5bb18819c981526bc15969e4b",
+ "object": "response",
+ "created_at": 1760704485,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-4o-2024-08-06",
+ "output": [
+ {
+ "id": "msg_03837d599fa2bb470168f237e6987c819c8c1f2bd707a5ecd0",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "The sum of 2 and 3 is 5, and their product is 6."
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": null,
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Add two numbers",
+ "name": "add",
+ "parameters": {
+ "properties": {
+ "a": {
+ "description": "first number",
+ "type": "integer"
+ },
+ "b": {
+ "description": "second number",
+ "type": "integer"
+ }
+ },
+ "required": [
+ "a",
+ "b"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ },
+ {
+ "type": "function",
+ "description": "Multiply two numbers",
+ "name": "multiply",
+ "parameters": {
+ "properties": {
+ "a": {
+ "description": "first number",
+ "type": "integer"
+ },
+ "b": {
+ "description": "second number",
+ "type": "integer"
+ }
+ },
+ "required": [
+ "a",
+ "b"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 156,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 21,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 177
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.167056291s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/multi_tool_streaming.yaml
new file mode 100644
index 000000000..0ed7ba6fe
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/multi_tool_streaming.yaml
@@ -0,0 +1,211 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 831
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":[{"text":"Add and multiply the number 2 and 3","type":"input_text"}],"role":"user"}],"model":"gpt-4o","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers","type":"function"},{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0ebade88a03470de0168f237e6e58c819c84da1c8ec78ba7d2","object":"response","created_at":1760704486,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0ebade88a03470de0168f237e6e58c819c84da1c8ec78ba7d2","object":"response","created_at":1760704486,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"fc_0ebade88a03470de0168f237e7cedc819c8e0e319d3639c441","type":"function_call","status":"in_progress","arguments":"","call_id":"call_zxaMct5MXAoxOlvCrfOtlCtZ","name":"add"}}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":3,"item_id":"fc_0ebade88a03470de0168f237e7cedc819c8e0e319d3639c441","output_index":0,"delta":"{","obfuscation":"fCJFJFNkp4P8bMx"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":4,"item_id":"fc_0ebade88a03470de0168f237e7cedc819c8e0e319d3639c441","output_index":0,"delta":"\"a","obfuscation":"O7MZLEoZ8gyHPI"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":5,"item_id":"fc_0ebade88a03470de0168f237e7cedc819c8e0e319d3639c441","output_index":0,"delta":"\":","obfuscation":"hTAm6x12gWo3K1"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":6,"item_id":"fc_0ebade88a03470de0168f237e7cedc819c8e0e319d3639c441","output_index":0,"delta":"2,","obfuscation":"kITfb9flbFOABd"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":7,"item_id":"fc_0ebade88a03470de0168f237e7cedc819c8e0e319d3639c441","output_index":0,"delta":"\"b","obfuscation":"xwg5ZiXbfokw7a"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":8,"item_id":"fc_0ebade88a03470de0168f237e7cedc819c8e0e319d3639c441","output_index":0,"delta":"\":","obfuscation":"dG0OUpvC8pgzeh"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":9,"item_id":"fc_0ebade88a03470de0168f237e7cedc819c8e0e319d3639c441","output_index":0,"delta":"3}","obfuscation":"XvcAKdjFk0itEn"}
+
+ event: response.function_call_arguments.done
+ data: {"type":"response.function_call_arguments.done","sequence_number":10,"item_id":"fc_0ebade88a03470de0168f237e7cedc819c8e0e319d3639c441","output_index":0,"arguments":"{\"a\":2,\"b\":3}"}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":11,"output_index":0,"item":{"id":"fc_0ebade88a03470de0168f237e7cedc819c8e0e319d3639c441","type":"function_call","status":"completed","arguments":"{\"a\":2,\"b\":3}","call_id":"call_zxaMct5MXAoxOlvCrfOtlCtZ","name":"add"}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":12,"output_index":1,"item":{"id":"fc_0ebade88a03470de0168f237e7dcb0819cb8bb0bf6e673c0f1","type":"function_call","status":"in_progress","arguments":"","call_id":"call_H0ZwSpO6zg8hQFdgz1R0mThA","name":"multiply"}}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":13,"item_id":"fc_0ebade88a03470de0168f237e7dcb0819cb8bb0bf6e673c0f1","output_index":1,"delta":"{","obfuscation":"YEf72OYRdag8Aj7"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":14,"item_id":"fc_0ebade88a03470de0168f237e7dcb0819cb8bb0bf6e673c0f1","output_index":1,"delta":"\"a","obfuscation":"5x1eNl800xF39X"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":15,"item_id":"fc_0ebade88a03470de0168f237e7dcb0819cb8bb0bf6e673c0f1","output_index":1,"delta":"\":","obfuscation":"iNZ5apaeClogAa"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":16,"item_id":"fc_0ebade88a03470de0168f237e7dcb0819cb8bb0bf6e673c0f1","output_index":1,"delta":"2,","obfuscation":"3OjGv8FBMD6cfB"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":17,"item_id":"fc_0ebade88a03470de0168f237e7dcb0819cb8bb0bf6e673c0f1","output_index":1,"delta":"\"b","obfuscation":"YsWSMGJeoKYcas"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":18,"item_id":"fc_0ebade88a03470de0168f237e7dcb0819cb8bb0bf6e673c0f1","output_index":1,"delta":"\":","obfuscation":"ntum9UcsMIC2oQ"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":19,"item_id":"fc_0ebade88a03470de0168f237e7dcb0819cb8bb0bf6e673c0f1","output_index":1,"delta":"3}","obfuscation":"cmtfNtk9UsX1US"}
+
+ event: response.function_call_arguments.done
+ data: {"type":"response.function_call_arguments.done","sequence_number":20,"item_id":"fc_0ebade88a03470de0168f237e7dcb0819cb8bb0bf6e673c0f1","output_index":1,"arguments":"{\"a\":2,\"b\":3}"}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":21,"output_index":1,"item":{"id":"fc_0ebade88a03470de0168f237e7dcb0819cb8bb0bf6e673c0f1","type":"function_call","status":"completed","arguments":"{\"a\":2,\"b\":3}","call_id":"call_H0ZwSpO6zg8hQFdgz1R0mThA","name":"multiply"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":22,"response":{"id":"resp_0ebade88a03470de0168f237e6e58c819c84da1c8ec78ba7d2","object":"response","created_at":1760704486,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[{"id":"fc_0ebade88a03470de0168f237e7cedc819c8e0e319d3639c441","type":"function_call","status":"completed","arguments":"{\"a\":2,\"b\":3}","call_id":"call_zxaMct5MXAoxOlvCrfOtlCtZ","name":"add"},{"id":"fc_0ebade88a03470de0168f237e7dcb0819cb8bb0bf6e673c0f1","type":"function_call","status":"completed","arguments":"{\"a\":2,\"b\":3}","call_id":"call_H0ZwSpO6zg8hQFdgz1R0mThA","name":"multiply"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":52,"input_tokens_details":{"cached_tokens":0},"output_tokens":50,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":102},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 239.5585ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1258
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":[{"text":"Add and multiply the number 2 and 3","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"a\\\":2,\\\"b\\\":3}\"","call_id":"call_zxaMct5MXAoxOlvCrfOtlCtZ","name":"add","type":"function_call"},{"arguments":"\"{\\\"a\\\":2,\\\"b\\\":3}\"","call_id":"call_H0ZwSpO6zg8hQFdgz1R0mThA","name":"multiply","type":"function_call"},{"call_id":"call_zxaMct5MXAoxOlvCrfOtlCtZ","output":"5","type":"function_call_output"},{"call_id":"call_H0ZwSpO6zg8hQFdgz1R0mThA","output":"6","type":"function_call_output"}],"model":"gpt-4o","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers","type":"function"},{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_077c121a3ca3329e0168f237e81de481a092d45b91e6588ae8","object":"response","created_at":1760704488,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_077c121a3ca3329e0168f237e81de481a092d45b91e6588ae8","object":"response","created_at":1760704488,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"2owrUCvUJFBUT"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":" sum","logprobs":[],"obfuscation":"cjzIn6Vw53ss"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"tPgTY5UTToAa3"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"b2fGuIhqxzmIlfy"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":"2","logprobs":[],"obfuscation":"4PmAyHYuNn7iGjN"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":" and","logprobs":[],"obfuscation":"gePgnHt9j6lR"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"YovNQ00Om1zFWv3"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":"3","logprobs":[],"obfuscation":"0PLD6BLk7xZ5IGs"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"gryllz0ZCrkI8"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"KD7wHvYxGbw7jiY"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":"5","logprobs":[],"obfuscation":"sjlU5yKhucEWC8I"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"Fmbamjkh4NwKk5q"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":" and","logprobs":[],"obfuscation":"HG6ynXHqm2ru"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"7criLQoQ65gL"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":" product","logprobs":[],"obfuscation":"meY9ncha"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"pjYCNpKQmBByY"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"84LNfyse8RA3FmS"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":"6","logprobs":[],"obfuscation":"HJPEBcOEzg5QCE2"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"xYOursICvKMAOqI"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":23,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"text":"The sum of 2 and 3 is 5, and the product is 6.","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":24,"item_id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"The sum of 2 and 3 is 5, and the product is 6."}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":25,"output_index":0,"item":{"id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The sum of 2 and 3 is 5, and the product is 6."}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":26,"response":{"id":"resp_077c121a3ca3329e0168f237e81de481a092d45b91e6588ae8","object":"response","created_at":1760704488,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[{"id":"msg_077c121a3ca3329e0168f237e87ebc81a0991d3b1ab9200eed","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The sum of 2 and 3 is 5, and the product is 6."}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":152,"input_tokens_details":{"cached_tokens":0},"output_tokens":21,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":173},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 239.102917ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/simple.yaml
new file mode 100644
index 000000000..d7f886b4c
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/simple.yaml
@@ -0,0 +1,100 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 205
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"system"},{"content":[{"text":"Say hi in Portuguese","type":"input_text"}],"role":"user"}],"model":"gpt-4o"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_07891da4b653e1470168f237de167081909c53deff29e333b8",
+ "object": "response",
+ "created_at": 1760704478,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-4o-2024-08-06",
+ "output": [
+ {
+ "id": "msg_07891da4b653e1470168f237deab0c8190be2fd9591e3d9afa",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "Ol\u00e1!"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": null,
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 20,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 3,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 23
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 941.245125ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/simple_streaming.yaml
new file mode 100644
index 000000000..5888c3586
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/simple_streaming.yaml
@@ -0,0 +1,62 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 219
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"system"},{"content":[{"text":"Say hi in Portuguese","type":"input_text"}],"role":"user"}],"model":"gpt-4o","stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_02a83fea833f7e430168f237dee7b08192a3ee0794d16e8574","object":"response","created_at":1760704478,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_02a83fea833f7e430168f237dee7b08192a3ee0794d16e8574","object":"response","created_at":1760704478,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_02a83fea833f7e430168f237df67988192ae502a743f847a80","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_02a83fea833f7e430168f237df67988192ae502a743f847a80","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_02a83fea833f7e430168f237df67988192ae502a743f847a80","output_index":0,"content_index":0,"delta":"OlĆ”","logprobs":[],"obfuscation":"PURwA0yAiQYg4"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_02a83fea833f7e430168f237df67988192ae502a743f847a80","output_index":0,"content_index":0,"delta":"!","logprobs":[],"obfuscation":"J47DmBbNkTc5h5k"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":6,"item_id":"msg_02a83fea833f7e430168f237df67988192ae502a743f847a80","output_index":0,"content_index":0,"text":"OlĆ”!","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":7,"item_id":"msg_02a83fea833f7e430168f237df67988192ae502a743f847a80","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"OlĆ”!"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":8,"output_index":0,"item":{"id":"msg_02a83fea833f7e430168f237df67988192ae502a743f847a80","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"OlĆ”!"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":9,"response":{"id":"resp_02a83fea833f7e430168f237dee7b08192a3ee0794d16e8574","object":"response","created_at":1760704478,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[{"id":"msg_02a83fea833f7e430168f237df67988192ae502a743f847a80","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"OlĆ”!"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":20,"input_tokens_details":{"cached_tokens":0},"output_tokens":3,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":23},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 232.38575ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/tool.yaml
new file mode 100644
index 000000000..dde370d5a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/tool.yaml
@@ -0,0 +1,229 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 484
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"system"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"}],"model":"gpt-4o","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_05f862a82ed768dc0168f237df9eac81a09b83a647320323a6",
+ "object": "response",
+ "created_at": 1760704479,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-4o-2024-08-06",
+ "output": [
+ {
+ "id": "fc_05f862a82ed768dc0168f237e0123c81a090b0b89afe5c9f72",
+ "type": "function_call",
+ "status": "completed",
+ "arguments": "{\"location\":\"Florence, Italy\"}",
+ "call_id": "call_jPXpCiiHqnkbYK8RbeLZfkLR",
+ "name": "weather"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": null,
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 58,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 17,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 75
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 777.148541ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 719
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"system"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_jPXpCiiHqnkbYK8RbeLZfkLR","name":"weather","type":"function_call"},{"call_id":"call_jPXpCiiHqnkbYK8RbeLZfkLR","output":"40 C","type":"function_call_output"}],"model":"gpt-4o","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_0122dddaaa9675250168f237e06e9481948f2a870e82765495",
+ "object": "response",
+ "created_at": 1760704480,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-4o-2024-08-06",
+ "output": [
+ {
+ "id": "msg_0122dddaaa9675250168f237e16ed481948bdad89376f1431a",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "The current temperature in Florence, Italy is 40\u00b0C. Stay cool and hydrated!"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": null,
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 83,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 19,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 102
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.512680875s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/tool_streaming.yaml
new file mode 100644
index 000000000..da55222c0
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-4o/tool_streaming.yaml
@@ -0,0 +1,163 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 498
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"system"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"}],"model":"gpt-4o","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0ac5f2ba0b4c0b830168f237e1ee10819dbe53070aa00ae06a","object":"response","created_at":1760704481,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0ac5f2ba0b4c0b830168f237e1ee10819dbe53070aa00ae06a","object":"response","created_at":1760704481,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"fc_0ac5f2ba0b4c0b830168f237e2f3d0819d8b008d01089913c8","type":"function_call","status":"in_progress","arguments":"","call_id":"call_Zvcj4GFYqfvf8AcNIB0Ra8is","name":"weather"}}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":3,"item_id":"fc_0ac5f2ba0b4c0b830168f237e2f3d0819d8b008d01089913c8","output_index":0,"delta":"{\"","obfuscation":"2GAUmPtuwiNdYV"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":4,"item_id":"fc_0ac5f2ba0b4c0b830168f237e2f3d0819d8b008d01089913c8","output_index":0,"delta":"location","obfuscation":"au0PIDR3"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":5,"item_id":"fc_0ac5f2ba0b4c0b830168f237e2f3d0819d8b008d01089913c8","output_index":0,"delta":"\":\"","obfuscation":"FJYeCiQOcRosn"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":6,"item_id":"fc_0ac5f2ba0b4c0b830168f237e2f3d0819d8b008d01089913c8","output_index":0,"delta":"Flor","obfuscation":"E9SXHAGEvpMC"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":7,"item_id":"fc_0ac5f2ba0b4c0b830168f237e2f3d0819d8b008d01089913c8","output_index":0,"delta":"ence","obfuscation":"Sezl9leQQI91"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":8,"item_id":"fc_0ac5f2ba0b4c0b830168f237e2f3d0819d8b008d01089913c8","output_index":0,"delta":",","obfuscation":"EL65bbUJbktS4Tq"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":9,"item_id":"fc_0ac5f2ba0b4c0b830168f237e2f3d0819d8b008d01089913c8","output_index":0,"delta":"Italy","obfuscation":"3paXU4gUFjJ"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":10,"item_id":"fc_0ac5f2ba0b4c0b830168f237e2f3d0819d8b008d01089913c8","output_index":0,"delta":"\"}","obfuscation":"RWw8uxX409IAgP"}
+
+ event: response.function_call_arguments.done
+ data: {"type":"response.function_call_arguments.done","sequence_number":11,"item_id":"fc_0ac5f2ba0b4c0b830168f237e2f3d0819d8b008d01089913c8","output_index":0,"arguments":"{\"location\":\"Florence,Italy\"}"}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":12,"output_index":0,"item":{"id":"fc_0ac5f2ba0b4c0b830168f237e2f3d0819d8b008d01089913c8","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence,Italy\"}","call_id":"call_Zvcj4GFYqfvf8AcNIB0Ra8is","name":"weather"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":13,"response":{"id":"resp_0ac5f2ba0b4c0b830168f237e1ee10819dbe53070aa00ae06a","object":"response","created_at":1760704481,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[{"id":"fc_0ac5f2ba0b4c0b830168f237e2f3d0819d8b008d01089913c8","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence,Italy\"}","call_id":"call_Zvcj4GFYqfvf8AcNIB0Ra8is","name":"weather"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":58,"input_tokens_details":{"cached_tokens":0},"output_tokens":17,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":75},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 259.382959ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 732
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"system"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"location\\\":\\\"Florence,Italy\\\"}\"","call_id":"call_Zvcj4GFYqfvf8AcNIB0Ra8is","name":"weather","type":"function_call"},{"call_id":"call_Zvcj4GFYqfvf8AcNIB0Ra8is","output":"40 C","type":"function_call_output"}],"model":"gpt-4o","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_06731cb9fb4e5ca10168f237e386788196af9a9096ab039479","object":"response","created_at":1760704483,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_06731cb9fb4e5ca10168f237e386788196af9a9096ab039479","object":"response","created_at":1760704483,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"Cgwi5P8IgS9WC"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","output_index":0,"content_index":0,"delta":" current","logprobs":[],"obfuscation":"E0r0sSyh"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","output_index":0,"content_index":0,"delta":" temperature","logprobs":[],"obfuscation":"RF23"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","output_index":0,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"jlg35ceRDkKXk"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","output_index":0,"content_index":0,"delta":" Florence","logprobs":[],"obfuscation":"EDwr3ta"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"FxbKO1NyhPWzcR4"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","output_index":0,"content_index":0,"delta":" Italy","logprobs":[],"obfuscation":"4DdeFdQGAC"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"jMNhe6GuRNzQb"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"gvoxDRWu7wmp9EI"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","output_index":0,"content_index":0,"delta":"40","logprobs":[],"obfuscation":"xNieQmyGcRt9XH"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","output_index":0,"content_index":0,"delta":"°C","logprobs":[],"obfuscation":"BkGN6qzwpQMLmt"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"wpXzyrGKXvqZ4cU"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":16,"item_id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","output_index":0,"content_index":0,"text":"The current temperature in Florence, Italy is 40°C.","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":17,"item_id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"The current temperature in Florence, Italy is 40°C."}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":18,"output_index":0,"item":{"id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current temperature in Florence, Italy is 40°C."}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":19,"response":{"id":"resp_06731cb9fb4e5ca10168f237e386788196af9a9096ab039479","object":"response","created_at":1760704483,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[{"id":"msg_06731cb9fb4e5ca10168f237e4477881968e966f3aca367554","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current temperature in Florence, Italy is 40°C."}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":83,"input_tokens_details":{"cached_tokens":0},"output_tokens":14,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":97},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 438.122375ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/multi_tool.yaml
new file mode 100644
index 000000000..b69208afb
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/multi_tool.yaml
@@ -0,0 +1,298 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 836
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"developer"},{"content":[{"text":"Add and multiply the number 2 and 3","type":"input_text"}],"role":"user"}],"model":"gpt-5","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers","type":"function"},{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_0a67406c0312cd3d0168f23808e21081a19469bdae7c79e9a1",
+ "object": "response",
+ "created_at": 1760704520,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-5-2025-08-07",
+ "output": [
+ {
+ "id": "rs_0a67406c0312cd3d0168f238093ecc81a1bdba7329dca10274",
+ "type": "reasoning",
+ "summary": []
+ },
+ {
+ "id": "fc_0a67406c0312cd3d0168f2380c363c81a185a8cb8507231fa5",
+ "type": "function_call",
+ "status": "completed",
+ "arguments": "{\"a\":2,\"b\":3}",
+ "call_id": "call_4zp4utiXe14bjLO4jtMZEjT9",
+ "name": "add"
+ },
+ {
+ "id": "fc_0a67406c0312cd3d0168f2380c544081a18909136702882f58",
+ "type": "function_call",
+ "status": "completed",
+ "arguments": "{\"a\":2,\"b\":3}",
+ "call_id": "call_4RkbJhNCkvdVClgNEsmTa3lb",
+ "name": "multiply"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Add two numbers",
+ "name": "add",
+ "parameters": {
+ "properties": {
+ "a": {
+ "description": "first number",
+ "type": "integer"
+ },
+ "b": {
+ "description": "second number",
+ "type": "integer"
+ }
+ },
+ "required": [
+ "a",
+ "b"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ },
+ {
+ "type": "function",
+ "description": "Multiply two numbers",
+ "name": "multiply",
+ "parameters": {
+ "properties": {
+ "a": {
+ "description": "first number",
+ "type": "integer"
+ },
+ "b": {
+ "description": "second number",
+ "type": "integer"
+ }
+ },
+ "required": [
+ "a",
+ "b"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 58,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 248,
+ "output_tokens_details": {
+ "reasoning_tokens": 192
+ },
+ "total_tokens": 306
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.821118208s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1263
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"developer"},{"content":[{"text":"Add and multiply the number 2 and 3","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"a\\\":2,\\\"b\\\":3}\"","call_id":"call_4zp4utiXe14bjLO4jtMZEjT9","name":"add","type":"function_call"},{"arguments":"\"{\\\"a\\\":2,\\\"b\\\":3}\"","call_id":"call_4RkbJhNCkvdVClgNEsmTa3lb","name":"multiply","type":"function_call"},{"call_id":"call_4zp4utiXe14bjLO4jtMZEjT9","output":"5","type":"function_call_output"},{"call_id":"call_4RkbJhNCkvdVClgNEsmTa3lb","output":"6","type":"function_call_output"}],"model":"gpt-5","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers","type":"function"},{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_02b2a4b073ba53220168f2380cb3a48190926547554955da24",
+ "object": "response",
+ "created_at": 1760704524,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-5-2025-08-07",
+ "output": [
+ {
+ "id": "msg_02b2a4b073ba53220168f2380d87508190bfa30618f00b704e",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "Results for the numbers 2 and 3:\n- Addition: 5\n- Multiplication: 6"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Add two numbers",
+ "name": "add",
+ "parameters": {
+ "properties": {
+ "a": {
+ "description": "first number",
+ "type": "integer"
+ },
+ "b": {
+ "description": "second number",
+ "type": "integer"
+ }
+ },
+ "required": [
+ "a",
+ "b"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ },
+ {
+ "type": "function",
+ "description": "Multiply two numbers",
+ "name": "multiply",
+ "parameters": {
+ "properties": {
+ "a": {
+ "description": "first number",
+ "type": "integer"
+ },
+ "b": {
+ "description": "second number",
+ "type": "integer"
+ }
+ },
+ "required": [
+ "a",
+ "b"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 176,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 26,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 202
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.3138075s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/multi_tool_streaming.yaml
new file mode 100644
index 000000000..f1dfe2581
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/multi_tool_streaming.yaml
@@ -0,0 +1,202 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 833
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"developer"},{"content":[{"text":"Add and multiply the number 2 and 3","type":"input_text"}],"role":"user"}],"model":"gpt-5","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers","type":"function"},{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_09e381d930f3da290168f2380e007c819eb0824a9f89df2473","object":"response","created_at":1760704526,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_09e381d930f3da290168f2380e007c819eb0824a9f89df2473","object":"response","created_at":1760704526,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_09e381d930f3da290168f2380e6048819e8e16dbff603275ca","type":"reasoning","summary":[]}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_09e381d930f3da290168f2380e6048819e8e16dbff603275ca","type":"reasoning","summary":[]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"fc_09e381d930f3da290168f23811471c819e9b878cd97d590c70","type":"function_call","status":"in_progress","arguments":"","call_id":"call_mM0OA8cwZxVibTLUQ0tgfuRL","name":"add"}}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":5,"item_id":"fc_09e381d930f3da290168f23811471c819e9b878cd97d590c70","output_index":1,"delta":"{","obfuscation":"A28LVm1DiTYj9iJ"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":6,"item_id":"fc_09e381d930f3da290168f23811471c819e9b878cd97d590c70","output_index":1,"delta":"\"a","obfuscation":"JPXaoVvKkpCAKM"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":7,"item_id":"fc_09e381d930f3da290168f23811471c819e9b878cd97d590c70","output_index":1,"delta":"\":","obfuscation":"uqXm9A6BWRrQW9"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":8,"item_id":"fc_09e381d930f3da290168f23811471c819e9b878cd97d590c70","output_index":1,"delta":"2,","obfuscation":"rSjqV8JLpcXCyy"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":9,"item_id":"fc_09e381d930f3da290168f23811471c819e9b878cd97d590c70","output_index":1,"delta":"\"b","obfuscation":"vHlTgn3pkcFggt"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":10,"item_id":"fc_09e381d930f3da290168f23811471c819e9b878cd97d590c70","output_index":1,"delta":"\":","obfuscation":"FGSSNQEHMtsOQ9"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":11,"item_id":"fc_09e381d930f3da290168f23811471c819e9b878cd97d590c70","output_index":1,"delta":"3}","obfuscation":"yQg8YUXPlb0xkd"}
+
+ event: response.function_call_arguments.done
+ data: {"type":"response.function_call_arguments.done","sequence_number":12,"item_id":"fc_09e381d930f3da290168f23811471c819e9b878cd97d590c70","output_index":1,"arguments":"{\"a\":2,\"b\":3}"}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":13,"output_index":1,"item":{"id":"fc_09e381d930f3da290168f23811471c819e9b878cd97d590c70","type":"function_call","status":"completed","arguments":"{\"a\":2,\"b\":3}","call_id":"call_mM0OA8cwZxVibTLUQ0tgfuRL","name":"add"}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":14,"output_index":2,"item":{"id":"fc_09e381d930f3da290168f238115664819ea231c4078a5f0376","type":"function_call","status":"in_progress","arguments":"","call_id":"call_ZN5JKJlLQZfBL7JTpEHES3Sm","name":"multiply"}}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":15,"item_id":"fc_09e381d930f3da290168f238115664819ea231c4078a5f0376","output_index":2,"delta":"{","obfuscation":"8dJcK7PD3X9jvxe"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":16,"item_id":"fc_09e381d930f3da290168f238115664819ea231c4078a5f0376","output_index":2,"delta":"\"a","obfuscation":"D9AcojCGoP0XoR"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":17,"item_id":"fc_09e381d930f3da290168f238115664819ea231c4078a5f0376","output_index":2,"delta":"\":","obfuscation":"LWpcm2Co0t9wOb"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":18,"item_id":"fc_09e381d930f3da290168f238115664819ea231c4078a5f0376","output_index":2,"delta":"2,","obfuscation":"mdBjj4nf2MtHzU"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":19,"item_id":"fc_09e381d930f3da290168f238115664819ea231c4078a5f0376","output_index":2,"delta":"\"b","obfuscation":"TCZjctdZylEM7V"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":20,"item_id":"fc_09e381d930f3da290168f238115664819ea231c4078a5f0376","output_index":2,"delta":"\":","obfuscation":"AW3CGCQsAgdcuq"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":21,"item_id":"fc_09e381d930f3da290168f238115664819ea231c4078a5f0376","output_index":2,"delta":"3}","obfuscation":"woholi6rbpmqFw"}
+
+ event: response.function_call_arguments.done
+ data: {"type":"response.function_call_arguments.done","sequence_number":22,"item_id":"fc_09e381d930f3da290168f238115664819ea231c4078a5f0376","output_index":2,"arguments":"{\"a\":2,\"b\":3}"}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":23,"output_index":2,"item":{"id":"fc_09e381d930f3da290168f238115664819ea231c4078a5f0376","type":"function_call","status":"completed","arguments":"{\"a\":2,\"b\":3}","call_id":"call_ZN5JKJlLQZfBL7JTpEHES3Sm","name":"multiply"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":24,"response":{"id":"resp_09e381d930f3da290168f2380e007c819eb0824a9f89df2473","object":"response","created_at":1760704526,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[{"id":"rs_09e381d930f3da290168f2380e6048819e8e16dbff603275ca","type":"reasoning","summary":[]},{"id":"fc_09e381d930f3da290168f23811471c819e9b878cd97d590c70","type":"function_call","status":"completed","arguments":"{\"a\":2,\"b\":3}","call_id":"call_mM0OA8cwZxVibTLUQ0tgfuRL","name":"add"},{"id":"fc_09e381d930f3da290168f238115664819ea231c4078a5f0376","type":"function_call","status":"completed","arguments":"{\"a\":2,\"b\":3}","call_id":"call_ZN5JKJlLQZfBL7JTpEHES3Sm","name":"multiply"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":56,"input_tokens_details":{"cached_tokens":0},"output_tokens":311,"output_tokens_details":{"reasoning_tokens":256},"total_tokens":367},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 283.240959ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1260
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"developer"},{"content":[{"text":"Add and multiply the number 2 and 3","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"a\\\":2,\\\"b\\\":3}\"","call_id":"call_mM0OA8cwZxVibTLUQ0tgfuRL","name":"add","type":"function_call"},{"arguments":"\"{\\\"a\\\":2,\\\"b\\\":3}\"","call_id":"call_ZN5JKJlLQZfBL7JTpEHES3Sm","name":"multiply","type":"function_call"},{"call_id":"call_mM0OA8cwZxVibTLUQ0tgfuRL","output":"5","type":"function_call_output"},{"call_id":"call_ZN5JKJlLQZfBL7JTpEHES3Sm","output":"6","type":"function_call_output"}],"model":"gpt-5","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"add","description":"Add two numbers","type":"function"},{"strict":false,"parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"name":"multiply","description":"Multiply two numbers","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_09bb7d797077bd810168f23811b088819fb2b1949e8dca30ed","object":"response","created_at":1760704529,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_09bb7d797077bd810168f23811b088819fb2b1949e8dca30ed","object":"response","created_at":1760704529,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"delta":"Results","logprobs":[],"obfuscation":"6StWlhs3v"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"delta":":\n","logprobs":[],"obfuscation":"7HlDzzfB4tGg8e"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"delta":"-","logprobs":[],"obfuscation":"aSgNiqlzrKxjwYJ"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"delta":" Addition","logprobs":[],"obfuscation":"1kIs9Fe"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"delta":":","logprobs":[],"obfuscation":"N8ePsIjPQkwgIIm"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"tDupEgp74kvVegn"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"delta":"5","logprobs":[],"obfuscation":"TXGo0Bhtqs0YNF5"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"delta":"\n","logprobs":[],"obfuscation":"sUe555ChDTIWxUy"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"delta":"-","logprobs":[],"obfuscation":"LnlsBondAJmfbak"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"delta":" Multip","logprobs":[],"obfuscation":"5vR7Ad1x4"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"delta":"lication","logprobs":[],"obfuscation":"2tYg9jRB"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"delta":":","logprobs":[],"obfuscation":"35cmlvHPfcNwftK"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"paqGVy5mDHZwDrl"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"delta":"6","logprobs":[],"obfuscation":"7GUVgOzItgYc95c"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":18,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"text":"Results:\n- Addition: 5\n- Multiplication: 6","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":19,"item_id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"Results:\n- Addition: 5\n- Multiplication: 6"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":20,"output_index":0,"item":{"id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"Results:\n- Addition: 5\n- Multiplication: 6"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":21,"response":{"id":"resp_09bb7d797077bd810168f23811b088819fb2b1949e8dca30ed","object":"response","created_at":1760704529,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[{"id":"msg_09bb7d797077bd810168f238125ad4819f84cc331e42e9f26c","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"Results:\n- Addition: 5\n- Multiplication: 6"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Add two numbers","name":"add","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false},{"type":"function","description":"Multiply two numbers","name":"multiply","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":172,"input_tokens_details":{"cached_tokens":0},"output_tokens":18,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":190},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 250.805041ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/simple.yaml
new file mode 100644
index 000000000..0d497eaf7
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/simple.yaml
@@ -0,0 +1,105 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 207
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"Say hi in Portuguese","type":"input_text"}],"role":"user"}],"model":"gpt-5"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_0b81ac5fdc5483560168f237f54ccc81968efa75aba7162889",
+ "object": "response",
+ "created_at": 1760704501,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-5-2025-08-07",
+ "output": [
+ {
+ "id": "rs_0b81ac5fdc5483560168f237f6618881968521aadd267daa6a",
+ "type": "reasoning",
+ "summary": []
+ },
+ {
+ "id": "msg_0b81ac5fdc5483560168f237f84b6c81968619287b3bf9dee9",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "Oi!"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 19,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 136,
+ "output_tokens_details": {
+ "reasoning_tokens": 128
+ },
+ "total_tokens": 155
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.478110792s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/simple_streaming.yaml
new file mode 100644
index 000000000..83dd08ea6
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/simple_streaming.yaml
@@ -0,0 +1,68 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 221
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"Say hi in Portuguese","type":"input_text"}],"role":"user"}],"model":"gpt-5","stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_06f879733b735e3a0168f237f8c33481a2ba14b36d6b67d967","object":"response","created_at":1760704504,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_06f879733b735e3a0168f237f8c33481a2ba14b36d6b67d967","object":"response","created_at":1760704504,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_06f879733b735e3a0168f237f941a481a28d55b9bcf8fe577c","type":"reasoning","summary":[]}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_06f879733b735e3a0168f237f941a481a28d55b9bcf8fe577c","type":"reasoning","summary":[]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"msg_06f879733b735e3a0168f237fac9c481a2b3a561bc2c54232c","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":5,"item_id":"msg_06f879733b735e3a0168f237fac9c481a2b3a561bc2c54232c","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_06f879733b735e3a0168f237fac9c481a2b3a561bc2c54232c","output_index":1,"content_index":0,"delta":"OlĆ”","logprobs":[],"obfuscation":"UqLDi4LzR6EDJ"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_06f879733b735e3a0168f237fac9c481a2b3a561bc2c54232c","output_index":1,"content_index":0,"delta":"!","logprobs":[],"obfuscation":"nohgR94nfxqT0xc"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":8,"item_id":"msg_06f879733b735e3a0168f237fac9c481a2b3a561bc2c54232c","output_index":1,"content_index":0,"text":"OlĆ”!","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":9,"item_id":"msg_06f879733b735e3a0168f237fac9c481a2b3a561bc2c54232c","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"OlĆ”!"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":10,"output_index":1,"item":{"id":"msg_06f879733b735e3a0168f237fac9c481a2b3a561bc2c54232c","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"OlĆ”!"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":11,"response":{"id":"resp_06f879733b735e3a0168f237f8c33481a2ba14b36d6b67d967","object":"response","created_at":1760704504,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[{"id":"rs_06f879733b735e3a0168f237f941a481a28d55b9bcf8fe577c","type":"reasoning","summary":[]},{"id":"msg_06f879733b735e3a0168f237fac9c481a2b3a561bc2c54232c","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"OlĆ”!"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":19,"input_tokens_details":{"cached_tokens":0},"output_tokens":136,"output_tokens_details":{"reasoning_tokens":128},"total_tokens":155},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 252.58825ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/tool.yaml
new file mode 100644
index 000000000..24587f0a9
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/tool.yaml
@@ -0,0 +1,239 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 486
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"}],"model":"gpt-5","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_03c1862e0741d1d40168f237fb21e88191bbe5c97d0994130f",
+ "object": "response",
+ "created_at": 1760704507,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-5-2025-08-07",
+ "output": [
+ {
+ "id": "rs_03c1862e0741d1d40168f237fb807c819194656e80eb126a65",
+ "type": "reasoning",
+ "summary": []
+ },
+ {
+ "id": "fc_03c1862e0741d1d40168f237fce0c88191a227de0e0fc29c2c",
+ "type": "function_call",
+ "status": "completed",
+ "arguments": "{\"location\":\"Florence, Italy\"}",
+ "call_id": "call_pG7sDgSfcLvcZrGGJrH3Z3aQ",
+ "name": "weather"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 66,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 86,
+ "output_tokens_details": {
+ "reasoning_tokens": 64
+ },
+ "total_tokens": 152
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.09006325s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 721
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_pG7sDgSfcLvcZrGGJrH3Z3aQ","name":"weather","type":"function_call"},{"call_id":"call_pG7sDgSfcLvcZrGGJrH3Z3aQ","output":"40 C","type":"function_call_output"}],"model":"gpt-5","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_00c0656fa55dff4a0168f237fd3b9c8196bd4e4de8737e9452",
+ "object": "response",
+ "created_at": 1760704509,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-5-2025-08-07",
+ "output": [
+ {
+ "id": "rs_00c0656fa55dff4a0168f237fdc064819691999ce73a7ce97a",
+ "type": "reasoning",
+ "summary": []
+ },
+ {
+ "id": "msg_00c0656fa55dff4a0168f2380148748196b3987065a61dba12",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "Right now in Florence, Italy it\u2019s about 40\u00b0C. Would you like the forecast or details like humidity and wind?"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 97,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 287,
+ "output_tokens_details": {
+ "reasoning_tokens": 256
+ },
+ "total_tokens": 384
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 4.618793667s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/tool_streaming.yaml
new file mode 100644
index 000000000..a64d062e5
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-gpt-5/tool_streaming.yaml
@@ -0,0 +1,217 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 500
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"}],"model":"gpt-5","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0f08b04cd21bd82c0168f23801d5c881a2b0d9b07784b8413a","object":"response","created_at":1760704513,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0f08b04cd21bd82c0168f23801d5c881a2b0d9b07784b8413a","object":"response","created_at":1760704513,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_0f08b04cd21bd82c0168f2380221f881a290014a36b8e479a4","type":"reasoning","summary":[]}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_0f08b04cd21bd82c0168f2380221f881a290014a36b8e479a4","type":"reasoning","summary":[]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"fc_0f08b04cd21bd82c0168f23803cc1481a28dc92074ab71c2e0","type":"function_call","status":"in_progress","arguments":"","call_id":"call_kGfQAVJ6MRnp9dXE2d0uYojD","name":"weather"}}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":5,"item_id":"fc_0f08b04cd21bd82c0168f23803cc1481a28dc92074ab71c2e0","output_index":1,"delta":"{\"","obfuscation":"xcxYsutrsF2Mr3"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":6,"item_id":"fc_0f08b04cd21bd82c0168f23803cc1481a28dc92074ab71c2e0","output_index":1,"delta":"location","obfuscation":"wSCxPmqE"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":7,"item_id":"fc_0f08b04cd21bd82c0168f23803cc1481a28dc92074ab71c2e0","output_index":1,"delta":"\":\"","obfuscation":"UNB0sKeiNNVya"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":8,"item_id":"fc_0f08b04cd21bd82c0168f23803cc1481a28dc92074ab71c2e0","output_index":1,"delta":"Flor","obfuscation":"nmio6Y5KgBCY"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":9,"item_id":"fc_0f08b04cd21bd82c0168f23803cc1481a28dc92074ab71c2e0","output_index":1,"delta":"ence","obfuscation":"dnccg49kl0GV"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":10,"item_id":"fc_0f08b04cd21bd82c0168f23803cc1481a28dc92074ab71c2e0","output_index":1,"delta":",","obfuscation":"zwu8CHinn8HhyUq"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":11,"item_id":"fc_0f08b04cd21bd82c0168f23803cc1481a28dc92074ab71c2e0","output_index":1,"delta":" Italy","obfuscation":"JrzifooHsu"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":12,"item_id":"fc_0f08b04cd21bd82c0168f23803cc1481a28dc92074ab71c2e0","output_index":1,"delta":"\"}","obfuscation":"EOPhpWvCbvwgkS"}
+
+ event: response.function_call_arguments.done
+ data: {"type":"response.function_call_arguments.done","sequence_number":13,"item_id":"fc_0f08b04cd21bd82c0168f23803cc1481a28dc92074ab71c2e0","output_index":1,"arguments":"{\"location\":\"Florence, Italy\"}"}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":14,"output_index":1,"item":{"id":"fc_0f08b04cd21bd82c0168f23803cc1481a28dc92074ab71c2e0","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence, Italy\"}","call_id":"call_kGfQAVJ6MRnp9dXE2d0uYojD","name":"weather"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":15,"response":{"id":"resp_0f08b04cd21bd82c0168f23801d5c881a2b0d9b07784b8413a","object":"response","created_at":1760704513,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[{"id":"rs_0f08b04cd21bd82c0168f2380221f881a290014a36b8e479a4","type":"reasoning","summary":[]},{"id":"fc_0f08b04cd21bd82c0168f23803cc1481a28dc92074ab71c2e0","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence, Italy\"}","call_id":"call_kGfQAVJ6MRnp9dXE2d0uYojD","name":"weather"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":66,"input_tokens_details":{"cached_tokens":0},"output_tokens":150,"output_tokens_details":{"reasoning_tokens":128},"total_tokens":216},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 281.778583ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 735
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_kGfQAVJ6MRnp9dXE2d0uYojD","name":"weather","type":"function_call"},{"call_id":"call_kGfQAVJ6MRnp9dXE2d0uYojD","output":"40 C","type":"function_call_output"}],"model":"gpt-5","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0eaa9d097b2a92720168f238043bb481929c94d445e6308cf0","object":"response","created_at":1760704516,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0eaa9d097b2a92720168f238043bb481929c94d445e6308cf0","object":"response","created_at":1760704516,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_0eaa9d097b2a92720168f23804ce888192b7336b8d4035a45d","type":"reasoning","summary":[]}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_0eaa9d097b2a92720168f23804ce888192b7336b8d4035a45d","type":"reasoning","summary":[]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":5,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":"It","logprobs":[],"obfuscation":"qcuOrpMigLjgYx"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":"ās","logprobs":[],"obfuscation":"BPKnl3lugU0n8Q"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":" currently","logprobs":[],"obfuscation":"MoQlwI"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":" about","logprobs":[],"obfuscation":"jJLAHeLcaa"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"T7DA0KFl7T9dCNp"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":"40","logprobs":[],"obfuscation":"iqIKIEx7Vvby8v"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":"°C","logprobs":[],"obfuscation":"Z6SUC2Ijtf39QQ"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":" (","logprobs":[],"obfuscation":"0fdEh8YqW52Eln"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":"104","logprobs":[],"obfuscation":"NPDD9eImQzTaO"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":"°F","logprobs":[],"obfuscation":"2v6RZJh1tMZuzH"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":")","logprobs":[],"obfuscation":"acclkkaR3ZuJLEO"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"mAqi3AUpM4err"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":" Florence","logprobs":[],"obfuscation":"EzqWNVR"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":",","logprobs":[],"obfuscation":"V9xzbMRz64sqFUh"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":" Italy","logprobs":[],"obfuscation":"0Icvry5xOU"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":".","logprobs":[],"obfuscation":"pmxPGojorJXet5q"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":" Would","logprobs":[],"obfuscation":"qbbDMSp9OW"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":" you","logprobs":[],"obfuscation":"aektY0mnj2fu"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":" like","logprobs":[],"obfuscation":"WHfweP6M2nZ"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":" today","logprobs":[],"obfuscation":"vKe3upqWqt"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":"ās","logprobs":[],"obfuscation":"NZe03vwqxO25tr"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":" forecast","logprobs":[],"obfuscation":"Mm5i3mS"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"SQ8WZNc7b96eu"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":29,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":" hourly","logprobs":[],"obfuscation":"rNTUCs5ZP"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":30,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":" details","logprobs":[],"obfuscation":"DCaRtQ80"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":31,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"delta":"?","logprobs":[],"obfuscation":"CunNisEbweeNHGk"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":32,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"text":"Itās currently about 40°C (104°F) in Florence, Italy. Would you like todayās forecast or hourly details?","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":33,"item_id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"Itās currently about 40°C (104°F) in Florence, Italy. Would you like todayās forecast or hourly details?"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":34,"output_index":1,"item":{"id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"Itās currently about 40°C (104°F) in Florence, Italy. Would you like todayās forecast or hourly details?"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":35,"response":{"id":"resp_0eaa9d097b2a92720168f238043bb481929c94d445e6308cf0","object":"response","created_at":1760704516,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[{"id":"rs_0eaa9d097b2a92720168f23804ce888192b7336b8d4035a45d","type":"reasoning","summary":[]},{"id":"msg_0eaa9d097b2a92720168f238084de88192bd4307c15498a6c0","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"Itās currently about 40°C (104°F) in Florence, Italy. Would you like todayās forecast or hourly details?"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":97,"input_tokens_details":{"cached_tokens":0},"output_tokens":288,"output_tokens_details":{"reasoning_tokens":256},"total_tokens":385},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 316.59475ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-o4-mini/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-o4-mini/simple.yaml
new file mode 100644
index 000000000..0fa6e17ea
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-o4-mini/simple.yaml
@@ -0,0 +1,105 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 209
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"Say hi in Portuguese","type":"input_text"}],"role":"user"}],"model":"o4-mini"}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_05edda4810c41de00168f23812e34481909c921eeab19085a0",
+ "object": "response",
+ "created_at": 1760704531,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "o4-mini-2025-04-16",
+ "output": [
+ {
+ "id": "rs_05edda4810c41de00168f2381383e08190b96c0313059265a9",
+ "type": "reasoning",
+ "summary": []
+ },
+ {
+ "id": "msg_05edda4810c41de00168f23814db48819083a54f56411e35a5",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "Oi!"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 19,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 136,
+ "output_tokens_details": {
+ "reasoning_tokens": 128
+ },
+ "total_tokens": 155
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.327569333s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-o4-mini/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-o4-mini/simple_streaming.yaml
new file mode 100644
index 000000000..e20550d6c
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-o4-mini/simple_streaming.yaml
@@ -0,0 +1,68 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 223
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"Say hi in Portuguese","type":"input_text"}],"role":"user"}],"model":"o4-mini","stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0374dd39c9ea81bb0168f2381531e88192bcc27c60d5000651","object":"response","created_at":1760704533,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0374dd39c9ea81bb0168f2381531e88192bcc27c60d5000651","object":"response","created_at":1760704533,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_0374dd39c9ea81bb0168f23815fe108192a9693e4138d05838","type":"reasoning","summary":[]}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_0374dd39c9ea81bb0168f23815fe108192a9693e4138d05838","type":"reasoning","summary":[]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"msg_0374dd39c9ea81bb0168f23816fc108192bbffb179beace674","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":5,"item_id":"msg_0374dd39c9ea81bb0168f23816fc108192bbffb179beace674","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_0374dd39c9ea81bb0168f23816fc108192bbffb179beace674","output_index":1,"content_index":0,"delta":"OlĆ”","logprobs":[],"obfuscation":"XyHUJi8uWmgQ3"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_0374dd39c9ea81bb0168f23816fc108192bbffb179beace674","output_index":1,"content_index":0,"delta":"!","logprobs":[],"obfuscation":"CKZwM0j52RoATdL"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":8,"item_id":"msg_0374dd39c9ea81bb0168f23816fc108192bbffb179beace674","output_index":1,"content_index":0,"text":"OlĆ”!","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":9,"item_id":"msg_0374dd39c9ea81bb0168f23816fc108192bbffb179beace674","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"OlĆ”!"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":10,"output_index":1,"item":{"id":"msg_0374dd39c9ea81bb0168f23816fc108192bbffb179beace674","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"OlĆ”!"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":11,"response":{"id":"resp_0374dd39c9ea81bb0168f2381531e88192bcc27c60d5000651","object":"response","created_at":1760704533,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[{"id":"rs_0374dd39c9ea81bb0168f23815fe108192a9693e4138d05838","type":"reasoning","summary":[]},{"id":"msg_0374dd39c9ea81bb0168f23816fc108192bbffb179beace674","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"OlĆ”!"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":19,"input_tokens_details":{"cached_tokens":0},"output_tokens":136,"output_tokens_details":{"reasoning_tokens":128},"total_tokens":155},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 283.477417ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-o4-mini/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-o4-mini/tool.yaml
new file mode 100644
index 000000000..34708fa79
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-o4-mini/tool.yaml
@@ -0,0 +1,234 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 488
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"}],"model":"o4-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_063e69ebba23c6e60168f238176014819580347bfecdcc350e",
+ "object": "response",
+ "created_at": 1760704535,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "o4-mini-2025-04-16",
+ "output": [
+ {
+ "id": "rs_063e69ebba23c6e60168f2381811ac8195bb719fa83683583a",
+ "type": "reasoning",
+ "summary": []
+ },
+ {
+ "id": "fc_063e69ebba23c6e60168f238191b248195a04018e0d0c747bb",
+ "type": "function_call",
+ "status": "completed",
+ "arguments": "{\"location\":\"Florence, Italy\"}",
+ "call_id": "call_3gTKulKFbPDpkRO7k5I0ffH2",
+ "name": "weather"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 60,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 150,
+ "output_tokens_details": {
+ "reasoning_tokens": 128
+ },
+ "total_tokens": 210
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.194950333s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 723
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_3gTKulKFbPDpkRO7k5I0ffH2","name":"weather","type":"function_call"},{"call_id":"call_3gTKulKFbPDpkRO7k5I0ffH2","output":"40 C","type":"function_call_output"}],"model":"o4-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_0bed20b0e88328550168f238198a5c81a0947a649d11fb2237",
+ "object": "response",
+ "created_at": 1760704537,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "o4-mini-2025-04-16",
+ "output": [
+ {
+ "id": "msg_0bed20b0e88328550168f23819fad081a090a3ce83d605449e",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "The current temperature in Florence, Italy is 40\u00b0C. It\u2019s quite hot! Make sure to stay hydrated, wear light clothing, and seek shade or air-conditioned places when possible. If you plan to be outdoors, consider going early in the morning or later in the evening to avoid peak heat."
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 91,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 64,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 155
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.272683542s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-o4-mini/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-o4-mini/tool_streaming.yaml
new file mode 100644
index 000000000..92d95d25a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesCommon/openai-o4-mini/tool_streaming.yaml
@@ -0,0 +1,169 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 502
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"}],"model":"o4-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0fff4a7c1f563e500168f2381ad21c819e8d405acd7b5d620a","object":"response","created_at":1760704538,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0fff4a7c1f563e500168f2381ad21c819e8d405acd7b5d620a","object":"response","created_at":1760704538,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_0fff4a7c1f563e500168f2381b32b0819ead0ce19c5404dec1","type":"reasoning","summary":[]}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_0fff4a7c1f563e500168f2381b32b0819ead0ce19c5404dec1","type":"reasoning","summary":[]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"fc_0fff4a7c1f563e500168f2381c9e38819e9f1631fafe9b714d","type":"function_call","status":"in_progress","arguments":"","call_id":"call_UszlYsP9zWWt4KA9WuQwyxdm","name":"weather"}}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":5,"item_id":"fc_0fff4a7c1f563e500168f2381c9e38819e9f1631fafe9b714d","output_index":1,"delta":"{\"","obfuscation":"0VOTJGynsRMloj"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":6,"item_id":"fc_0fff4a7c1f563e500168f2381c9e38819e9f1631fafe9b714d","output_index":1,"delta":"location","obfuscation":"43dCYsDX"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":7,"item_id":"fc_0fff4a7c1f563e500168f2381c9e38819e9f1631fafe9b714d","output_index":1,"delta":"\":\"","obfuscation":"rc3sKD04Npkkf"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":8,"item_id":"fc_0fff4a7c1f563e500168f2381c9e38819e9f1631fafe9b714d","output_index":1,"delta":"Flor","obfuscation":"s3bnH4WQP4Cb"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":9,"item_id":"fc_0fff4a7c1f563e500168f2381c9e38819e9f1631fafe9b714d","output_index":1,"delta":"ence","obfuscation":"y9JNPlQMT6YX"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":10,"item_id":"fc_0fff4a7c1f563e500168f2381c9e38819e9f1631fafe9b714d","output_index":1,"delta":",","obfuscation":"w8Zt7ULkOyHEuSK"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":11,"item_id":"fc_0fff4a7c1f563e500168f2381c9e38819e9f1631fafe9b714d","output_index":1,"delta":" Italy","obfuscation":"6GaIjNSMTu"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":12,"item_id":"fc_0fff4a7c1f563e500168f2381c9e38819e9f1631fafe9b714d","output_index":1,"delta":"\"}","obfuscation":"4eavzEAMPbOXlx"}
+
+ event: response.function_call_arguments.done
+ data: {"type":"response.function_call_arguments.done","sequence_number":13,"item_id":"fc_0fff4a7c1f563e500168f2381c9e38819e9f1631fafe9b714d","output_index":1,"arguments":"{\"location\":\"Florence, Italy\"}"}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":14,"output_index":1,"item":{"id":"fc_0fff4a7c1f563e500168f2381c9e38819e9f1631fafe9b714d","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence, Italy\"}","call_id":"call_UszlYsP9zWWt4KA9WuQwyxdm","name":"weather"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":15,"response":{"id":"resp_0fff4a7c1f563e500168f2381ad21c819e8d405acd7b5d620a","object":"response","created_at":1760704538,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[{"id":"rs_0fff4a7c1f563e500168f2381b32b0819ead0ce19c5404dec1","type":"reasoning","summary":[]},{"id":"fc_0fff4a7c1f563e500168f2381c9e38819e9f1631fafe9b714d","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence, Italy\"}","call_id":"call_UszlYsP9zWWt4KA9WuQwyxdm","name":"weather"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":60,"input_tokens_details":{"cached_tokens":0},"output_tokens":150,"output_tokens_details":{"reasoning_tokens":128},"total_tokens":210},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 241.611625ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 737
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence,Italy?","type":"input_text"}],"role":"user"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_UszlYsP9zWWt4KA9WuQwyxdm","name":"weather","type":"function_call"},{"call_id":"call_UszlYsP9zWWt4KA9WuQwyxdm","output":"40 C","type":"function_call_output"}],"model":"o4-mini","tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0dcc08c733ff71550168f2381d2a1081a2846a305f27bbc863","object":"response","created_at":1760704541,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0dcc08c733ff71550168f2381d2a1081a2846a305f27bbc863","object":"response","created_at":1760704541,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"eyjSsgALEwhaq"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","output_index":0,"content_index":0,"delta":" current","logprobs":[],"obfuscation":"8lINdioG"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","output_index":0,"content_index":0,"delta":" temperature","logprobs":[],"obfuscation":"iz5j"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","output_index":0,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"tJkN0FEyXaK8s"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","output_index":0,"content_index":0,"delta":" Florence","logprobs":[],"obfuscation":"n0EpdRL"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"xAWfObum6kfDhuQ"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","output_index":0,"content_index":0,"delta":" Italy","logprobs":[],"obfuscation":"SJOq4btOnE"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"8HoJkvOcK3Jsc"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"51n6LMmqmV5C73I"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","output_index":0,"content_index":0,"delta":"40","logprobs":[],"obfuscation":"MPplkcPECUV7Pv"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","output_index":0,"content_index":0,"delta":"°C","logprobs":[],"obfuscation":"MiSC5pzAiiBwR4"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"H2yQ4qGmNmJhbhZ"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":16,"item_id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","output_index":0,"content_index":0,"text":"The current temperature in Florence, Italy is 40°C.","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":17,"item_id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"The current temperature in Florence, Italy is 40°C."}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":18,"output_index":0,"item":{"id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current temperature in Florence, Italy is 40°C."}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":19,"response":{"id":"resp_0dcc08c733ff71550168f2381d2a1081a2846a305f27bbc863","object":"response","created_at":1760704541,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[{"id":"msg_0dcc08c733ff71550168f2381d703881a280ee31f3e6de9bdc","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current temperature in Florence, Italy is 40°C."}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":91,"input_tokens_details":{"cached_tokens":0},"output_tokens":16,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":107},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 235.374ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o-mini/complex_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o-mini/complex_object.yaml
new file mode 100644
index 000000000..a6c1a5c23
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o-mini/complex_object.yaml
@@ -0,0 +1,149 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 915
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":[{"text":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","type":"input_text"}],"role":"user"}],"model":"gpt-4o-mini","text":{"format":{"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"type":"json_schema"}}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_00aee193a62b03b301690fb5e67a8481a0890292ac13193180",
+ "object": "response",
+ "created_at": 1762637286,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-4o-mini-2024-07-18",
+ "output": [
+ {
+ "id": "msg_00aee193a62b03b301690fb5e6bf6881a0ab198f7831a11cf0",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\",\"Epic\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "prompt_cache_retention": null,
+ "reasoning": {
+ "effort": null,
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "json_schema",
+ "description": null,
+ "name": "Book",
+ "schema": {
+ "additionalProperties": false,
+ "properties": {
+ "author": {
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "description": "Author's name",
+ "type": "string"
+ },
+ "nationality": {
+ "description": "Author's nationality",
+ "type": "string"
+ }
+ },
+ "required": [
+ "name",
+ "nationality"
+ ],
+ "type": "object"
+ },
+ "genres": {
+ "description": "List of genres",
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "published_year": {
+ "description": "Year the book was published",
+ "type": "integer"
+ },
+ "title": {
+ "description": "The book title",
+ "type": "string"
+ }
+ },
+ "required": [
+ "title",
+ "author",
+ "genres",
+ "published_year"
+ ],
+ "type": "object"
+ },
+ "strict": true
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 140,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 41,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 181
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.153408417s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o-mini/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o-mini/complex_object_streaming.yaml
new file mode 100644
index 000000000..74d720ef4
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o-mini/complex_object_streaming.yaml
@@ -0,0 +1,176 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 929
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":[{"text":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","type":"input_text"}],"role":"user"}],"model":"gpt-4o-mini","text":{"format":{"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"type":"json_schema"}},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0b395c22c64bd0de01690fb5e7a238819ca85a64e9b6ac32f9","object":"response","created_at":1762637287,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0b395c22c64bd0de01690fb5e7a238819ca85a64e9b6ac32f9","object":"response","created_at":1762637287,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"{\"","logprobs":[],"obfuscation":"w0uRy397P1tlme"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"author","logprobs":[],"obfuscation":"UZSUIL51HD"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"\":{\"","logprobs":[],"obfuscation":"U2IqPfEyuCW6"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"name","logprobs":[],"obfuscation":"6yodA173gW37"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"jS3ejVQkBmYE3"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"J","logprobs":[],"obfuscation":"iroZ6WuFyfK1VZx"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":".R","logprobs":[],"obfuscation":"KInGWlQdImRYQg"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":".R","logprobs":[],"obfuscation":"iqZyszfl4LmbgS"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"IbIFqu9ECqk6OJi"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":" Tolkien","logprobs":[],"obfuscation":"ayMpSFlJ"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"\",\"","logprobs":[],"obfuscation":"73YsvDPY3GKaG"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"national","logprobs":[],"obfuscation":"QlFktnnV"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"ity","logprobs":[],"obfuscation":"v3rMNOTO15LY2"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"vIbvcS93WrAED"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"British","logprobs":[],"obfuscation":"vUvh0fBq3"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"\"}","logprobs":[],"obfuscation":"ot4OdWrjqe1tui"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":",\"","logprobs":[],"obfuscation":"vlKgFxiUSzmVij"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"genres","logprobs":[],"obfuscation":"XUqVQBjShJ"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"\":[\"","logprobs":[],"obfuscation":"AzfakgEtflt4"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"Fantasy","logprobs":[],"obfuscation":"IKhUZs45d"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"\",\"","logprobs":[],"obfuscation":"PWSU5F7JRKRYT"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"Adventure","logprobs":[],"obfuscation":"WrMADZ8"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"\",\"","logprobs":[],"obfuscation":"1NxVYWia8J4H7"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"Epic","logprobs":[],"obfuscation":"mD8StL2RnA6u"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"\"],","logprobs":[],"obfuscation":"kQQLUU3Sy011a"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":29,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"\"","logprobs":[],"obfuscation":"oQydHGyZqlEEgJj"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":30,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"published","logprobs":[],"obfuscation":"EC59oD9"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":31,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"_year","logprobs":[],"obfuscation":"8MRn2RjtLJ6"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":32,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"\":","logprobs":[],"obfuscation":"fF4nUJIrWxRwMy"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":33,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"195","logprobs":[],"obfuscation":"29LJXcHAZMBkr"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":34,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"4","logprobs":[],"obfuscation":"wTk4EbM8GGejI1J"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":35,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":",\"","logprobs":[],"obfuscation":"FsbpZWLfvqurzA"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":36,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"title","logprobs":[],"obfuscation":"WHXlPFGiuyP"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":37,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"2E0ywqxSMIzML"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":38,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"3qqlFQsPWsxQq"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":39,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":" Lord","logprobs":[],"obfuscation":"J2hT3a8DD3T"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":40,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"WxRGBxwiWEOrb"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":41,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"flD8BqwGg6lR"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":42,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":" Rings","logprobs":[],"obfuscation":"mHXsGxleFl"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":43,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"delta":"\"}","logprobs":[],"obfuscation":"kJzjigwFnkmYsp"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":44,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"text":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\",\"Epic\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":45,"item_id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\",\"Epic\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":46,"output_index":0,"item":{"id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\",\"Epic\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":47,"response":{"id":"resp_0b395c22c64bd0de01690fb5e7a238819ca85a64e9b6ac32f9","object":"response","created_at":1762637287,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[{"id":"msg_0b395c22c64bd0de01690fb5e7d34c819c84dc831a681cfeaa","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\",\"Epic\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":140,"input_tokens_details":{"cached_tokens":0},"output_tokens":41,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":181},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 189.690709ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o-mini/simple_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o-mini/simple_object.yaml
new file mode 100644
index 000000000..9e1cca0af
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o-mini/simple_object.yaml
@@ -0,0 +1,127 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 570
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris.","type":"input_text"}],"role":"user"}],"model":"gpt-4o-mini","text":{"format":{"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"},"type":"json_schema"}}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_0bbc50a7c5ff86f001690fb5e419a8819087b97bd3cbc4c406",
+ "object": "response",
+ "created_at": 1762637284,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-4o-mini-2024-07-18",
+ "output": [
+ {
+ "id": "msg_0bbc50a7c5ff86f001690fb5e4fabc8190a9749a3e0c928bce",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "prompt_cache_retention": null,
+ "reasoning": {
+ "effort": null,
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "json_schema",
+ "description": null,
+ "name": "Person",
+ "schema": {
+ "additionalProperties": false,
+ "properties": {
+ "age": {
+ "description": "The person's age",
+ "type": "integer"
+ },
+ "city": {
+ "description": "The city where the person lives",
+ "type": "string"
+ },
+ "name": {
+ "description": "The person's name",
+ "type": "string"
+ }
+ },
+ "required": [
+ "name",
+ "age",
+ "city"
+ ],
+ "type": "object"
+ },
+ "strict": true
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 82,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 14,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 96
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.465307584s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o-mini/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o-mini/simple_object_streaming.yaml
new file mode 100644
index 000000000..97758429c
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o-mini/simple_object_streaming.yaml
@@ -0,0 +1,95 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 584
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris.","type":"input_text"}],"role":"user"}],"model":"gpt-4o-mini","text":{"format":{"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"},"type":"json_schema"}},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_02c04886274e996201690fb5e586cc819e964a8d2266867d18","object":"response","created_at":1762637285,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_02c04886274e996201690fb5e586cc819e964a8d2266867d18","object":"response","created_at":1762637285,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","output_index":0,"content_index":0,"delta":"{\"","logprobs":[],"obfuscation":"8Z8tlCzwEPiKxX"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","output_index":0,"content_index":0,"delta":"age","logprobs":[],"obfuscation":"ntrGNnjEMQo9S"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","output_index":0,"content_index":0,"delta":"\":","logprobs":[],"obfuscation":"JnvWExEm2crgkL"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","output_index":0,"content_index":0,"delta":"30","logprobs":[],"obfuscation":"e7D0BYaAV7ZZan"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","output_index":0,"content_index":0,"delta":",\"","logprobs":[],"obfuscation":"nKINeWVP6PC4J6"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","output_index":0,"content_index":0,"delta":"city","logprobs":[],"obfuscation":"BSUszpyTPPQM"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","output_index":0,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"e2xJqxLyd6dLg"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","output_index":0,"content_index":0,"delta":"Paris","logprobs":[],"obfuscation":"hFKgDAqf1y5"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","output_index":0,"content_index":0,"delta":"\",\"","logprobs":[],"obfuscation":"BnhyOi3WfoTgj"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","output_index":0,"content_index":0,"delta":"name","logprobs":[],"obfuscation":"Rwn7qYlbLykn"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","output_index":0,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"ejkwCmkYwp6jc"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","output_index":0,"content_index":0,"delta":"Alice","logprobs":[],"obfuscation":"eTPamAFYtjC"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","output_index":0,"content_index":0,"delta":"\"}","logprobs":[],"obfuscation":"cRZBPSZqiONzJX"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":17,"item_id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","output_index":0,"content_index":0,"text":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":18,"item_id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":19,"output_index":0,"item":{"id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":20,"response":{"id":"resp_02c04886274e996201690fb5e586cc819e964a8d2266867d18","object":"response","created_at":1762637285,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-mini-2024-07-18","output":[{"id":"msg_02c04886274e996201690fb5e617b4819eaec84bdb3206fa59","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":82,"input_tokens_details":{"cached_tokens":0},"output_tokens":14,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":96},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 179.409584ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o/complex_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o/complex_object.yaml
new file mode 100644
index 000000000..cc1732174
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o/complex_object.yaml
@@ -0,0 +1,149 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 910
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":[{"text":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","type":"input_text"}],"role":"user"}],"model":"gpt-4o","text":{"format":{"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"type":"json_schema"}}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_00fee2bcbce77a6b01690fb5e194848191a77c3f9796902417",
+ "object": "response",
+ "created_at": 1762637281,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-4o-2024-08-06",
+ "output": [
+ {
+ "id": "msg_00fee2bcbce77a6b01690fb5e25dfc8191b275e2c92a87865a",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "prompt_cache_retention": null,
+ "reasoning": {
+ "effort": null,
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "json_schema",
+ "description": null,
+ "name": "Book",
+ "schema": {
+ "additionalProperties": false,
+ "properties": {
+ "author": {
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "description": "Author's name",
+ "type": "string"
+ },
+ "nationality": {
+ "description": "Author's nationality",
+ "type": "string"
+ }
+ },
+ "required": [
+ "name",
+ "nationality"
+ ],
+ "type": "object"
+ },
+ "genres": {
+ "description": "List of genres",
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "published_year": {
+ "description": "Year the book was published",
+ "type": "integer"
+ },
+ "title": {
+ "description": "The book title",
+ "type": "string"
+ }
+ },
+ "required": [
+ "title",
+ "author",
+ "genres",
+ "published_year"
+ ],
+ "type": "object"
+ },
+ "strict": true
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 140,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 39,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 179
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.348413375s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o/complex_object_streaming.yaml
new file mode 100644
index 000000000..5cbb82e32
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o/complex_object_streaming.yaml
@@ -0,0 +1,176 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 924
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":[{"text":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","type":"input_text"}],"role":"user"}],"model":"gpt-4o","text":{"format":{"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"type":"json_schema"}},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0cd0345c54b0381e01690fb5e2f140819eb8b9fa3f55b4313b","object":"response","created_at":1762637282,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0cd0345c54b0381e01690fb5e2f140819eb8b9fa3f55b4313b","object":"response","created_at":1762637282,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"{\"","logprobs":[],"obfuscation":"rqbg0m6QYeXgew"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"author","logprobs":[],"obfuscation":"imJpYwjkk0"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"\":{\"","logprobs":[],"obfuscation":"lneI4feOIym9"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"name","logprobs":[],"obfuscation":"aX9sLDq2ShNV"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"KiEnVxgS9idJH"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"J","logprobs":[],"obfuscation":"NZgdxXG8Ah2sXsw"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":".R","logprobs":[],"obfuscation":"HFw9pvQ76Llxwp"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":".R","logprobs":[],"obfuscation":"8zX1xDihGzxkHf"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"N40FWmzYdfGMc7i"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":" Tolkien","logprobs":[],"obfuscation":"G4r8UC5e"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"\",\"","logprobs":[],"obfuscation":"2F9mZioKQNsdU"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"national","logprobs":[],"obfuscation":"TzITeG8Q"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"ity","logprobs":[],"obfuscation":"MSB3tbOfmt5ht"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"hEEegRwybEaou"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"British","logprobs":[],"obfuscation":"g52xWMqPz"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"\"}","logprobs":[],"obfuscation":"pTei8sG6eaYajt"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":",\"","logprobs":[],"obfuscation":"EVHqJ8sE2pknJ6"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"genres","logprobs":[],"obfuscation":"IdiOODGbkg"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"\":[\"","logprobs":[],"obfuscation":"Lp0dktegOY6a"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"Fantasy","logprobs":[],"obfuscation":"aHGrVouuy"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"\",\"","logprobs":[],"obfuscation":"WhmcIASKcGkdi"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"Adventure","logprobs":[],"obfuscation":"vzUnini"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"\",\"","logprobs":[],"obfuscation":"y7pdOOLQxnNQ7"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"Epic","logprobs":[],"obfuscation":"u5Qlk4ltcPiM"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"\"],","logprobs":[],"obfuscation":"fxlKRgBuiXrcS"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":29,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"\"","logprobs":[],"obfuscation":"NNbHospqb8d07Gv"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":30,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"published","logprobs":[],"obfuscation":"zxP33mg"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":31,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"_year","logprobs":[],"obfuscation":"mkUcspqZlnl"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":32,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"\":","logprobs":[],"obfuscation":"9fbDJimUlNNP8Y"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":33,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"195","logprobs":[],"obfuscation":"EHiBUrbpr2ElG"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":34,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"4","logprobs":[],"obfuscation":"bqVfSL9VMxSkmFe"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":35,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":",\"","logprobs":[],"obfuscation":"qgmBIyTIfjH3OE"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":36,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"title","logprobs":[],"obfuscation":"Id8zVfGYo7a"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":37,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"veHzdRv23AzPl"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":38,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"xMnThoyDxhbUr"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":39,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":" Lord","logprobs":[],"obfuscation":"OcJRWqXfn1M"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":40,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"3TOyEkURJ6dVm"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":41,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"FlHWLd9puSSA"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":42,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":" Rings","logprobs":[],"obfuscation":"8yvK9lspkq"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":43,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"delta":"\"}","logprobs":[],"obfuscation":"XDCCShjSwvlmkK"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":44,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"text":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\",\"Epic\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":45,"item_id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\",\"Epic\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":46,"output_index":0,"item":{"id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\",\"Epic\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":47,"response":{"id":"resp_0cd0345c54b0381e01690fb5e2f140819eb8b9fa3f55b4313b","object":"response","created_at":1762637282,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[{"id":"msg_0cd0345c54b0381e01690fb5e33790819e8d4550f3ccc5c05f","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\",\"Epic\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":140,"input_tokens_details":{"cached_tokens":0},"output_tokens":41,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":181},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 204.676208ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o/simple_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o/simple_object.yaml
new file mode 100644
index 000000000..736c50953
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o/simple_object.yaml
@@ -0,0 +1,127 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 565
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris.","type":"input_text"}],"role":"user"}],"model":"gpt-4o","text":{"format":{"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"},"type":"json_schema"}}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_0f20344bcc1b767601690fb5e04c9c81a08af63f829b10bb55",
+ "object": "response",
+ "created_at": 1762637280,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-4o-2024-08-06",
+ "output": [
+ {
+ "id": "msg_0f20344bcc1b767601690fb5e094e481a0833865218a771607",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "prompt_cache_retention": null,
+ "reasoning": {
+ "effort": null,
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "json_schema",
+ "description": null,
+ "name": "Person",
+ "schema": {
+ "additionalProperties": false,
+ "properties": {
+ "age": {
+ "description": "The person's age",
+ "type": "integer"
+ },
+ "city": {
+ "description": "The city where the person lives",
+ "type": "string"
+ },
+ "name": {
+ "description": "The person's name",
+ "type": "string"
+ }
+ },
+ "required": [
+ "name",
+ "age",
+ "city"
+ ],
+ "type": "object"
+ },
+ "strict": true
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 82,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 14,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 96
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 816.505042ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o/simple_object_streaming.yaml
new file mode 100644
index 000000000..ba035949d
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-4o/simple_object_streaming.yaml
@@ -0,0 +1,95 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 579
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris.","type":"input_text"}],"role":"user"}],"model":"gpt-4o","text":{"format":{"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"},"type":"json_schema"}},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0d165ceb975b9af401690fb5e0e8788192bd9eb948decabbd1","object":"response","created_at":1762637280,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0d165ceb975b9af401690fb5e0e8788192bd9eb948decabbd1","object":"response","created_at":1762637280,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","output_index":0,"content_index":0,"delta":"{\"","logprobs":[],"obfuscation":"Tp0jZ8gJ4woL9Y"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","output_index":0,"content_index":0,"delta":"age","logprobs":[],"obfuscation":"citwa9boDP9Y2"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","output_index":0,"content_index":0,"delta":"\":","logprobs":[],"obfuscation":"y41U42sTULTK18"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","output_index":0,"content_index":0,"delta":"30","logprobs":[],"obfuscation":"YqlEplTbGy3fsj"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","output_index":0,"content_index":0,"delta":",\"","logprobs":[],"obfuscation":"Sg3V1re96l7ZKF"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","output_index":0,"content_index":0,"delta":"city","logprobs":[],"obfuscation":"x357HhG0WmSG"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","output_index":0,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"y0CAsSO6TE2Wm"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","output_index":0,"content_index":0,"delta":"Paris","logprobs":[],"obfuscation":"B7NTDCRqRbF"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","output_index":0,"content_index":0,"delta":"\",\"","logprobs":[],"obfuscation":"IETmenhLsNCo2"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","output_index":0,"content_index":0,"delta":"name","logprobs":[],"obfuscation":"tN74YVJx0gab"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","output_index":0,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"sFnNvr3rmQHWV"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","output_index":0,"content_index":0,"delta":"Alice","logprobs":[],"obfuscation":"5fQecM4hrZO"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","output_index":0,"content_index":0,"delta":"\"}","logprobs":[],"obfuscation":"jgrv8Q1bo52G7r"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":17,"item_id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","output_index":0,"content_index":0,"text":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":18,"item_id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":19,"output_index":0,"item":{"id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":20,"response":{"id":"resp_0d165ceb975b9af401690fb5e0e8788192bd9eb948decabbd1","object":"response","created_at":1762637280,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-4o-2024-08-06","output":[{"id":"msg_0d165ceb975b9af401690fb5e147e08192981f80e775d1b42a","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":null,"summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":82,"input_tokens_details":{"cached_tokens":0},"output_tokens":14,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":96},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 229.655875ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-5/complex_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-5/complex_object.yaml
new file mode 100644
index 000000000..117e01dd7
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-5/complex_object.yaml
@@ -0,0 +1,154 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 909
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":[{"text":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","type":"input_text"}],"role":"user"}],"model":"gpt-5","text":{"format":{"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"type":"json_schema"}}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_0d7efb113168df8301690fb603c0f881a1a5ecec45f910e875",
+ "object": "response",
+ "created_at": 1762637315,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-5-2025-08-07",
+ "output": [
+ {
+ "id": "rs_0d7efb113168df8301690fb6041bb881a198a6e417f00bba70",
+ "type": "reasoning",
+ "summary": []
+ },
+ {
+ "id": "msg_0d7efb113168df8301690fb610bf2881a1be28a4885c1876ac",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\",\"Epic fantasy\",\"High fantasy\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "prompt_cache_retention": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "json_schema",
+ "description": null,
+ "name": "Book",
+ "schema": {
+ "additionalProperties": false,
+ "properties": {
+ "author": {
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "description": "Author's name",
+ "type": "string"
+ },
+ "nationality": {
+ "description": "Author's nationality",
+ "type": "string"
+ }
+ },
+ "required": [
+ "name",
+ "nationality"
+ ],
+ "type": "object"
+ },
+ "genres": {
+ "description": "List of genres",
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "published_year": {
+ "description": "Year the book was published",
+ "type": "integer"
+ },
+ "title": {
+ "description": "The book title",
+ "type": "string"
+ }
+ },
+ "required": [
+ "title",
+ "author",
+ "genres",
+ "published_year"
+ ],
+ "type": "object"
+ },
+ "strict": true
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 138,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 885,
+ "output_tokens_details": {
+ "reasoning_tokens": 832
+ },
+ "total_tokens": 1023
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 13.745367625s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-5/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-5/complex_object_streaming.yaml
new file mode 100644
index 000000000..a8dbf4720
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-5/complex_object_streaming.yaml
@@ -0,0 +1,191 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 923
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":[{"text":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","type":"input_text"}],"role":"user"}],"model":"gpt-5","text":{"format":{"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"type":"json_schema"}},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0aab0755c068dba601690fb61193ac81a09b187ec6ae118666","object":"response","created_at":1762637329,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0aab0755c068dba601690fb61193ac81a09b187ec6ae118666","object":"response","created_at":1762637329,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_0aab0755c068dba601690fb611f3ac81a09cdf0bc7455763c3","type":"reasoning","summary":[]}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_0aab0755c068dba601690fb611f3ac81a09cdf0bc7455763c3","type":"reasoning","summary":[]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":5,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"{\"","logprobs":[],"obfuscation":"FRSE2Xg4Zlm8ZC"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"author","logprobs":[],"obfuscation":"yOVxZwnwPd"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"\":{\"","logprobs":[],"obfuscation":"2gdH3UjKn7p9"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"name","logprobs":[],"obfuscation":"yC1JPv5XOR2N"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"tX53HlJF35P9H"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"J","logprobs":[],"obfuscation":"EtaQPdRl67MBSep"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":".R","logprobs":[],"obfuscation":"inIyKyyMrOUvqS"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":".R","logprobs":[],"obfuscation":"EILjTviSrTF0ld"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":".","logprobs":[],"obfuscation":"yLLwcS41h3upq9Y"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":" Tolkien","logprobs":[],"obfuscation":"8exzRdOu"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"\",\"","logprobs":[],"obfuscation":"mnj6f7Tx86gFa"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"national","logprobs":[],"obfuscation":"kTAXhH1C"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"ity","logprobs":[],"obfuscation":"lmCwZO8RmMwd2"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"mwjZzCk2nZQe9"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"British","logprobs":[],"obfuscation":"EyvRvxuBK"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"\"}","logprobs":[],"obfuscation":"hfEkZupXjk2638"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":",\"","logprobs":[],"obfuscation":"IsmwSfSFAcAJcU"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"genres","logprobs":[],"obfuscation":"IQtYupB5bm"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"\":[\"","logprobs":[],"obfuscation":"9IAahn76FgpL"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"Fantasy","logprobs":[],"obfuscation":"OMHBvYUds"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"\",\"","logprobs":[],"obfuscation":"HlxU6WDUGwneu"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"Adventure","logprobs":[],"obfuscation":"ech2Vhw"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"\",\"","logprobs":[],"obfuscation":"AKMMJLmgtycDx"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":29,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"Epic","logprobs":[],"obfuscation":"t209VHDHFuLF"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":30,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"\",\"","logprobs":[],"obfuscation":"Cr6RboWi7ioxS"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":31,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"High","logprobs":[],"obfuscation":"obU3L2eqqyS4"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":32,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":" fantasy","logprobs":[],"obfuscation":"LUcEZc9a"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":33,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"\"],","logprobs":[],"obfuscation":"mntl6wRF0Z9vj"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":34,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"\"","logprobs":[],"obfuscation":"i8cTb3WH2EqqLnM"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":35,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"published","logprobs":[],"obfuscation":"aMJKxsW"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":36,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"_year","logprobs":[],"obfuscation":"ZXgdO0bgvI8"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":37,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"\":","logprobs":[],"obfuscation":"oHU9zp2d7ZBE8r"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":38,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"195","logprobs":[],"obfuscation":"wDjlyAPKySdjw"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":39,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"4","logprobs":[],"obfuscation":"YhVTDZXJht9Deaa"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":40,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":",\"","logprobs":[],"obfuscation":"uzKH47tBdPXm2n"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":41,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"title","logprobs":[],"obfuscation":"aXOJbtxSFSA"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":42,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"ni9nsl8eAvHWp"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":43,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"secEK5zivRAr9"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":44,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":" Lord","logprobs":[],"obfuscation":"tTvtm7dHyTk"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":45,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"2LbYZOGAwQHVR"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":46,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"06rgzxqdEmme"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":47,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":" Rings","logprobs":[],"obfuscation":"x7YNUbaBsm"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":48,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"delta":"\"}","logprobs":[],"obfuscation":"RgRi11lh9YHnhK"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":49,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"text":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\",\"Epic\",\"High fantasy\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":50,"item_id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\",\"Epic\",\"High fantasy\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":51,"output_index":1,"item":{"id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\",\"Epic\",\"High fantasy\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":52,"response":{"id":"resp_0aab0755c068dba601690fb61193ac81a09b187ec6ae118666","object":"response","created_at":1762637329,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[{"id":"rs_0aab0755c068dba601690fb611f3ac81a09cdf0bc7455763c3","type":"reasoning","summary":[]},{"id":"msg_0aab0755c068dba601690fb61b054481a08336dd277cca7e31","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"British\"},\"genres\":[\"Fantasy\",\"Adventure\",\"Epic\",\"High fantasy\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":138,"input_tokens_details":{"cached_tokens":0},"output_tokens":628,"output_tokens_details":{"reasoning_tokens":576},"total_tokens":766},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 305.219208ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-5/simple_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-5/simple_object.yaml
new file mode 100644
index 000000000..5383b0d91
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-5/simple_object.yaml
@@ -0,0 +1,132 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 564
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris.","type":"input_text"}],"role":"user"}],"model":"gpt-5","text":{"format":{"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"},"type":"json_schema"}}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_027d860ff8453c5c01690fb5e8b590819c98d4fefe82a2d697",
+ "object": "response",
+ "created_at": 1762637288,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "gpt-5-2025-08-07",
+ "output": [
+ {
+ "id": "rs_027d860ff8453c5c01690fb5e90bf8819cafd2ab51156cc379",
+ "type": "reasoning",
+ "summary": []
+ },
+ {
+ "id": "msg_027d860ff8453c5c01690fb5fe2978819ca252f996006bf96e",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "prompt_cache_retention": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "json_schema",
+ "description": null,
+ "name": "Person",
+ "schema": {
+ "additionalProperties": false,
+ "properties": {
+ "age": {
+ "description": "The person's age",
+ "type": "integer"
+ },
+ "city": {
+ "description": "The city where the person lives",
+ "type": "string"
+ },
+ "name": {
+ "description": "The person's name",
+ "type": "string"
+ }
+ },
+ "required": [
+ "name",
+ "age",
+ "city"
+ ],
+ "type": "object"
+ },
+ "strict": true
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 80,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 1238,
+ "output_tokens_details": {
+ "reasoning_tokens": 1216
+ },
+ "total_tokens": 1318
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 22.08059475s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-5/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-5/simple_object_streaming.yaml
new file mode 100644
index 000000000..ac2f26b05
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-gpt-5/simple_object_streaming.yaml
@@ -0,0 +1,101 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 578
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris.","type":"input_text"}],"role":"user"}],"model":"gpt-5","text":{"format":{"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"},"type":"json_schema"}},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0f3ec5120e1249d801690fb5fecea8819da2de394f03b31ace","object":"response","created_at":1762637310,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0f3ec5120e1249d801690fb5fecea8819da2de394f03b31ace","object":"response","created_at":1762637310,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_0f3ec5120e1249d801690fb5ff2974819dba13ad28975c504b","type":"reasoning","summary":[]}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_0f3ec5120e1249d801690fb5ff2974819dba13ad28975c504b","type":"reasoning","summary":[]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":5,"item_id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","output_index":1,"content_index":0,"delta":"{\"","logprobs":[],"obfuscation":"7GTnOqQFxPeOpK"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","output_index":1,"content_index":0,"delta":"age","logprobs":[],"obfuscation":"ahq3wJcqDg67C"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","output_index":1,"content_index":0,"delta":"\":","logprobs":[],"obfuscation":"osUjj5cRs2ORzR"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","output_index":1,"content_index":0,"delta":"30","logprobs":[],"obfuscation":"5eJ5yJuRiS5WN3"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","output_index":1,"content_index":0,"delta":",\"","logprobs":[],"obfuscation":"e7TX0qCwG2Lo3U"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","output_index":1,"content_index":0,"delta":"city","logprobs":[],"obfuscation":"YwOQpDl4Ogwh"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","output_index":1,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"ZHxRR3Nq8o8BN"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","output_index":1,"content_index":0,"delta":"Paris","logprobs":[],"obfuscation":"t5OlzBTusIz"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","output_index":1,"content_index":0,"delta":"\",\"","logprobs":[],"obfuscation":"UxQ64dgXht7OW"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","output_index":1,"content_index":0,"delta":"name","logprobs":[],"obfuscation":"QrSseCXd0dr7"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","output_index":1,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"UGFZp4OC4WO91"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","output_index":1,"content_index":0,"delta":"Alice","logprobs":[],"obfuscation":"tsJ1GFIhmG1"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","output_index":1,"content_index":0,"delta":"\"}","logprobs":[],"obfuscation":"abWOYlvE9UO8wT"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":19,"item_id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","output_index":1,"content_index":0,"text":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":20,"item_id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":21,"output_index":1,"item":{"id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":22,"response":{"id":"resp_0f3ec5120e1249d801690fb5fecea8819da2de394f03b31ace","object":"response","created_at":1762637310,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[{"id":"rs_0f3ec5120e1249d801690fb5ff2974819dba13ad28975c504b","type":"reasoning","summary":[]},{"id":"msg_0f3ec5120e1249d801690fb6033aa0819db234a634e05d5a30","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":80,"input_tokens_details":{"cached_tokens":0},"output_tokens":214,"output_tokens_details":{"reasoning_tokens":192},"total_tokens":294},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 217.170041ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-o4-mini/complex_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-o4-mini/complex_object.yaml
new file mode 100644
index 000000000..cbea589d6
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-o4-mini/complex_object.yaml
@@ -0,0 +1,154 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 911
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":[{"text":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","type":"input_text"}],"role":"user"}],"model":"o4-mini","text":{"format":{"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"type":"json_schema"}}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_017b2c309fa6f10301690fb622abf481a0a85dad143f87cc57",
+ "object": "response",
+ "created_at": 1762637346,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "o4-mini-2025-04-16",
+ "output": [
+ {
+ "id": "rs_017b2c309fa6f10301690fb623133881a0b253929605c93041",
+ "type": "reasoning",
+ "summary": []
+ },
+ {
+ "id": "msg_017b2c309fa6f10301690fb6269d6c81a0abb3acf886a1efe0",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"English\"},\"genres\":[\"Fantasy\",\"Adventure\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "prompt_cache_retention": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "json_schema",
+ "description": null,
+ "name": "Book",
+ "schema": {
+ "additionalProperties": false,
+ "properties": {
+ "author": {
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "description": "Author's name",
+ "type": "string"
+ },
+ "nationality": {
+ "description": "Author's nationality",
+ "type": "string"
+ }
+ },
+ "required": [
+ "name",
+ "nationality"
+ ],
+ "type": "object"
+ },
+ "genres": {
+ "description": "List of genres",
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "published_year": {
+ "description": "Year the book was published",
+ "type": "integer"
+ },
+ "title": {
+ "description": "The book title",
+ "type": "string"
+ }
+ },
+ "required": [
+ "title",
+ "author",
+ "genres",
+ "published_year"
+ ],
+ "type": "object"
+ },
+ "strict": true
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 138,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 431,
+ "output_tokens_details": {
+ "reasoning_tokens": 384
+ },
+ "total_tokens": 569
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 4.660075375s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-o4-mini/complex_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-o4-mini/complex_object_streaming.yaml
new file mode 100644
index 000000000..a33dac621
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-o4-mini/complex_object_streaming.yaml
@@ -0,0 +1,176 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 925
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":[{"text":"Generate information about ''The Lord of the Rings'' book by J.R.R. Tolkien, including genres like fantasy and adventure, and its publication year (1954).","type":"input_text"}],"role":"user"}],"model":"o4-mini","text":{"format":{"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author''s name","type":"string"},"nationality":{"description":"Author''s nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"type":"json_schema"}},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0feabf3ec12ead7701690fb62757bc81a09ca434178fe08235","object":"response","created_at":1762637351,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0feabf3ec12ead7701690fb62757bc81a09ca434178fe08235","object":"response","created_at":1762637351,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_0feabf3ec12ead7701690fb62796f881a0b162227941dc79ef","type":"reasoning","summary":[]}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_0feabf3ec12ead7701690fb62796f881a0b162227941dc79ef","type":"reasoning","summary":[]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":5,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"{\"","logprobs":[],"obfuscation":"UKrPeS79BSa2RR"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"author","logprobs":[],"obfuscation":"4HYFJNddaM"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"\":{\"","logprobs":[],"obfuscation":"KxfmMUbv6rSi"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"name","logprobs":[],"obfuscation":"hK7kM7NKGjH6"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"6wHz01JjOsAH0"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"J","logprobs":[],"obfuscation":"bNKD05FCk2HtePG"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":".R","logprobs":[],"obfuscation":"cut8dbqMYbhOnj"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":".R","logprobs":[],"obfuscation":"nvA4l6kpG3sJEu"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":".","logprobs":[],"obfuscation":"QrOGoNp8B9iFZL4"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":" Tolkien","logprobs":[],"obfuscation":"IH7RJtC7"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"\",\"","logprobs":[],"obfuscation":"Js54Ii28VMaYR"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"national","logprobs":[],"obfuscation":"7nLZE4t9"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"ity","logprobs":[],"obfuscation":"5vI2FTTXwlAOy"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"wUMHr1ru5bQtE"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"English","logprobs":[],"obfuscation":"lsI0ms9i1"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"\"}","logprobs":[],"obfuscation":"aRrNa6GpujOaaO"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":",\"","logprobs":[],"obfuscation":"Kt3i52uXhZ03Mf"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"genres","logprobs":[],"obfuscation":"G1WDFmbb9Q"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"\":[\"","logprobs":[],"obfuscation":"6O7ClIrlzRhF"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"Fantasy","logprobs":[],"obfuscation":"wkIXL8F1U"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"\",\"","logprobs":[],"obfuscation":"dKXLAcp4XePv8"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"Adventure","logprobs":[],"obfuscation":"WqXwtaT"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"\"],","logprobs":[],"obfuscation":"TdJkB47ahMYzw"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":29,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"\"","logprobs":[],"obfuscation":"IMl8aiOGDVVszW4"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":30,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"published","logprobs":[],"obfuscation":"epu511F"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":31,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"_year","logprobs":[],"obfuscation":"nQ0Lilgt6ou"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":32,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"\":","logprobs":[],"obfuscation":"PSA5xVUFXYVr6g"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":33,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"195","logprobs":[],"obfuscation":"UNVN1tMqPGaBa"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":34,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"4","logprobs":[],"obfuscation":"RoUacQkG36iqsQT"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":35,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":",\"","logprobs":[],"obfuscation":"WoGTOtmNLBtcdp"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":36,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"title","logprobs":[],"obfuscation":"tdpLqHv2M45"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":37,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"2H1pTP6cRXFKQ"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":38,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"XyHCviQ1pz0nu"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":39,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":" Lord","logprobs":[],"obfuscation":"ZJPCj7Z7IG0"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":40,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"t8V077vZPcKp9"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":41,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"UuQWm1gxDQnK"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":42,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":" Rings","logprobs":[],"obfuscation":"UYyiAtjL19"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":43,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"delta":"\"}","logprobs":[],"obfuscation":"fFubIsqj7lUp0g"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":44,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"text":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"English\"},\"genres\":[\"Fantasy\",\"Adventure\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":45,"item_id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"English\"},\"genres\":[\"Fantasy\",\"Adventure\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":46,"output_index":1,"item":{"id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"English\"},\"genres\":[\"Fantasy\",\"Adventure\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":47,"response":{"id":"resp_0feabf3ec12ead7701690fb62757bc81a09ca434178fe08235","object":"response","created_at":1762637351,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[{"id":"rs_0feabf3ec12ead7701690fb62796f881a0b162227941dc79ef","type":"reasoning","summary":[]},{"id":"msg_0feabf3ec12ead7701690fb62cbd0c81a08295b29b09eeda24","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"author\":{\"name\":\"J.R.R. Tolkien\",\"nationality\":\"English\"},\"genres\":[\"Fantasy\",\"Adventure\"],\"published_year\":1954,\"title\":\"The Lord of the Rings\"}"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Book","schema":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"properties":{"name":{"description":"Author's name","type":"string"},"nationality":{"description":"Author's nationality","type":"string"}},"required":["name","nationality"],"type":"object"},"genres":{"description":"List of genres","items":{"type":"string"},"type":"array"},"published_year":{"description":"Year the book was published","type":"integer"},"title":{"description":"The book title","type":"string"}},"required":["title","author","genres","published_year"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":138,"input_tokens_details":{"cached_tokens":0},"output_tokens":431,"output_tokens_details":{"reasoning_tokens":384},"total_tokens":569},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 257.810458ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-o4-mini/simple_object.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-o4-mini/simple_object.yaml
new file mode 100644
index 000000000..731fefffb
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-o4-mini/simple_object.yaml
@@ -0,0 +1,132 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 566
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris.","type":"input_text"}],"role":"user"}],"model":"o4-mini","text":{"format":{"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"},"type":"json_schema"}}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_098f453613ad314501690fb61bc6e0819382952362bbb4e647",
+ "object": "response",
+ "created_at": 1762637339,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": 4000,
+ "max_tool_calls": null,
+ "model": "o4-mini-2025-04-16",
+ "output": [
+ {
+ "id": "rs_098f453613ad314501690fb61c869c81939eea265ba983fa58",
+ "type": "reasoning",
+ "summary": []
+ },
+ {
+ "id": "msg_098f453613ad314501690fb61f8828819389d543a45e07bc0b",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "prompt_cache_retention": null,
+ "reasoning": {
+ "effort": "medium",
+ "summary": null
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "json_schema",
+ "description": null,
+ "name": "Person",
+ "schema": {
+ "additionalProperties": false,
+ "properties": {
+ "age": {
+ "description": "The person's age",
+ "type": "integer"
+ },
+ "city": {
+ "description": "The city where the person lives",
+ "type": "string"
+ },
+ "name": {
+ "description": "The person's name",
+ "type": "string"
+ }
+ },
+ "required": [
+ "name",
+ "age",
+ "city"
+ ],
+ "type": "object"
+ },
+ "strict": true
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 80,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 342,
+ "output_tokens_details": {
+ "reasoning_tokens": 320
+ },
+ "total_tokens": 422
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 4.174928125s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-o4-mini/simple_object_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-o4-mini/simple_object_streaming.yaml
new file mode 100644
index 000000000..e802239e8
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesObjectGeneration/openai-o4-mini/simple_object_streaming.yaml
@@ -0,0 +1,101 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 580
+ host: ""
+ body: '{"max_output_tokens":4000,"store":false,"input":[{"content":[{"text":"Generate information about a person named Alice who is 30 years old and lives in Paris.","type":"input_text"}],"role":"user"}],"model":"o4-mini","text":{"format":{"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person''s age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person''s name","type":"string"}},"required":["name","age","city"],"type":"object"},"type":"json_schema"}},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_092dac14c3675a9901690fb61fee90819f92f6cd6a5129655b","object":"response","created_at":1762637343,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_092dac14c3675a9901690fb61fee90819f92f6cd6a5129655b","object":"response","created_at":1762637343,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_092dac14c3675a9901690fb6206d14819f8e540e484376b314","type":"reasoning","summary":[]}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_092dac14c3675a9901690fb6206d14819f8e540e484376b314","type":"reasoning","summary":[]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":5,"item_id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","output_index":1,"content_index":0,"delta":"{\"","logprobs":[],"obfuscation":"RaOJnqjM3VMFeX"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","output_index":1,"content_index":0,"delta":"age","logprobs":[],"obfuscation":"CHzhDPf4XW2LQ"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","output_index":1,"content_index":0,"delta":"\":","logprobs":[],"obfuscation":"aPilRCMMML2n5Z"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","output_index":1,"content_index":0,"delta":"30","logprobs":[],"obfuscation":"WCYnVeEqYrabrv"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","output_index":1,"content_index":0,"delta":",\"","logprobs":[],"obfuscation":"8TEJwUIK3jbPWi"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","output_index":1,"content_index":0,"delta":"city","logprobs":[],"obfuscation":"vJNJD3fm6lN3"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","output_index":1,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"jHpf1NTinBnYc"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","output_index":1,"content_index":0,"delta":"Paris","logprobs":[],"obfuscation":"2CDW692CQMC"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","output_index":1,"content_index":0,"delta":"\",\"","logprobs":[],"obfuscation":"Tu4CGFL4JfOj1"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","output_index":1,"content_index":0,"delta":"name","logprobs":[],"obfuscation":"RfV3CrSjJYW6"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","output_index":1,"content_index":0,"delta":"\":\"","logprobs":[],"obfuscation":"aQM4HvXYeHWW4"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","output_index":1,"content_index":0,"delta":"Alice","logprobs":[],"obfuscation":"TBbzJB26w73"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","output_index":1,"content_index":0,"delta":"\"}","logprobs":[],"obfuscation":"PIppQ9A3zqutnN"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":19,"item_id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","output_index":1,"content_index":0,"text":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":20,"item_id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","output_index":1,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":21,"output_index":1,"item":{"id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":22,"response":{"id":"resp_092dac14c3675a9901690fb61fee90819f92f6cd6a5129655b","object":"response","created_at":1762637343,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":4000,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[{"id":"rs_092dac14c3675a9901690fb6206d14819f8e540e484376b314","type":"reasoning","summary":[]},{"id":"msg_092dac14c3675a9901690fb6224a44819fa81dd0010f806bce","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"{\"age\":30,\"city\":\"Paris\",\"name\":\"Alice\"}"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"prompt_cache_retention":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"json_schema","description":null,"name":"Person","schema":{"additionalProperties":false,"properties":{"age":{"description":"The person's age","type":"integer"},"city":{"description":"The city where the person lives","type":"string"},"name":{"description":"The person's name","type":"string"}},"required":["name","age","city"],"type":"object"},"strict":true},"verbosity":"medium"},"tool_choice":"auto","tools":[],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":80,"input_tokens_details":{"cached_tokens":0},"output_tokens":214,"output_tokens_details":{"reasoning_tokens":192},"total_tokens":294},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 191.94075ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesWithSummaryThinking/openai-gpt-5/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesWithSummaryThinking/openai-gpt-5/thinking-streaming.yaml
new file mode 100644
index 000000000..5c9da36e5
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesWithSummaryThinking/openai-gpt-5/thinking-streaming.yaml
@@ -0,0 +1,499 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 565
+ host: ""
+ body: '{"store":false,"include":["reasoning.encrypted_content"],"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence, Italy?","type":"input_text"}],"role":"user"}],"model":"gpt-5","reasoning":{"effort":"high","summary":"auto"},"tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_00564a370f8761470168f239a3f90c819492eb21bd9b25c369","object":"response","created_at":1760704932,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_00564a370f8761470168f239a3f90c819492eb21bd9b25c369","object":"response","created_at":1760704932,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","type":"reasoning","encrypted_content":"gAAAAABo8jmkhn3gO_TMlHP7zrmqSQK6e2YwCe3YftZKY9Y9Am0N47nufS0EOe2c40Ie_ULjJ_I4NfuJMK2z4f-hl32bIn-6n_VLQtWy0JNg5qIiYspMtmsGPDKY0PqVj8rmYPrrH6UBrnmjOIwiBy-owTkt4-iRe7p39ooEi23aAg7edh9Cus926ptNWnCyRd5LBxp_pLeUBbjcnyZKbN8sHpHkYBXi-d3tKM1w5RKtWwNk1iYZeSpMnFeu-0Rh6ybotX-rx9IRZceu-zOBPpk0Be52EqZGZNZtB7mmsfX9VainX3PHsAviBrwTJH5dSBMpRft_Mw0YE-rVBCcCRk-aDqJbxDgxndIFci_GHsu-iPuwV-kyIGiIMT_m1n_DSnQAkdY5Ur9gLMu0x91oug9mePtyoUf5SEIw4HLUVRESBhxg1pZr-QR1dv-qTjjyaJnRVQFEFcaKxUxRbKUEoMP3T1sg72LBP2kh6t9GtwNjPD5S63TjWBGogzHfOlc2WmiMzG6B0kY9xFh7wIM9XqbRvggxnNK37ltLB57lL73RckCP_4A2rLypjDmeewnDF0xLsKjVh_KHMMMrcMro__2EDnCIMpyWn5PFlEqHoAn1XcL81NSSxqgc12LYfTy4AddcrLUyNY0TDoV7J40oprdDPmD7SdTPcg9j4NXyQcDwcs_rsa_mtY4XH--Qd7EdCCOETDAaHi8uzz1Ig1gHGE-2sivK_NCqIUjX9IifDBZ_EycsiRhvoqKK58aE6ZxAKMzuvQZSGid9avuGUzO_bSvuCLVfYMeLsR2twj__CX6yXLvkHy3WebfqsABEFbklAp1A3ZAn17FJ","summary":[]}}
+
+ event: response.reasoning_summary_part.added
+ data: {"type":"response.reasoning_summary_part.added","sequence_number":3,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"part":{"type":"summary_text","text":""}}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":4,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":"I","obfuscation":"7DRBaSVGkoaUAGo"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":5,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" need","obfuscation":"1X0SoR7ISWG"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":6,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" to","obfuscation":"rthsd0jwgCyFz"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":7,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" remember","obfuscation":"ovHzzWZ"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":8,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" that","obfuscation":"uFz4k3UMlvC"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":9,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" the","obfuscation":"ltZlzfZ0yU6l"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":10,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" system","obfuscation":"8E6OkTKuV"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":11,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" indicates","obfuscation":"gTEV0Q"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":12,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" today's","obfuscation":"fpcWImre"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":13,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" date","obfuscation":"XYRrFEZomsM"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":14,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" as","obfuscation":"O3uyLbWk7Rkyf"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":15,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" October","obfuscation":"vqWPqbvD"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":16,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" 17","obfuscation":"nJ0JxYcuYNPaP"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":17,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":",","obfuscation":"zoEdGGnU4ew1zgL"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":18,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" 202","obfuscation":"YHWc9ZA6FhfW"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":19,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":"5","obfuscation":"ocF7ItddWql3cK8"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":20,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":".","obfuscation":"OFEXxPmTEfDageA"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":21,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" However","obfuscation":"AuUibTSe"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":22,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":",","obfuscation":"djJeFeKA9erQeeF"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":23,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" it","obfuscation":"oOgKLlZwbAhf2"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":24,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" seems","obfuscation":"ppPNCSReg7"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":25,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" the","obfuscation":"N1D0YyAZN45u"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":26,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" weather","obfuscation":"gy2PjbA7"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":27,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" tool","obfuscation":"ahaAH7nhXKw"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":28,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" will","obfuscation":"fELLVUIuNhf"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":29,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" return","obfuscation":"WJCOBWkkN"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":30,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" the","obfuscation":"HLJ5Lrkofh1F"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":31,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" current","obfuscation":"zDz8Xlwy"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":32,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" weather","obfuscation":"9sgtkxk6"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":33,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" for","obfuscation":"perCAhVfTp77"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":34,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" that","obfuscation":"IKnXSFx60T2"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":35,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" date","obfuscation":"wXTCiZMX0Yo"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":36,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":",","obfuscation":"OB0ZYz037xsGeqj"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":37,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" rather","obfuscation":"lwAfwyfW2"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":38,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" than","obfuscation":"jtqrK627sv2"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":39,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" needing","obfuscation":"4LIaWi4q"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":40,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" to","obfuscation":"LjZd0BxFmKd5P"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":41,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" compute","obfuscation":"ZY6FmwGa"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":42,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" anything","obfuscation":"GuLZ2Jd"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":43,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" myself","obfuscation":"xqbdXPCfq"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":44,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":".","obfuscation":"QgpXIz4jnu1hii2"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":45,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" So","obfuscation":"wtUgYnlNPIOWc"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":46,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":",","obfuscation":"tinbfhauzusl6jC"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":47,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" I","obfuscation":"Pk3zXd2ujZwFvW"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":48,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":"āll","obfuscation":"x4BYAA4LKTuDo"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":49,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" just","obfuscation":"BIoUZZ3HSrt"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":50,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" go","obfuscation":"K7O5Owrq7A9lp"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":51,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" ahead","obfuscation":"is6hy5rFhR"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":52,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" and","obfuscation":"huqqJhQunTsB"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":53,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" call","obfuscation":"Bycx7BVhk4X"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":54,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" the","obfuscation":"2iNIq7zihEyp"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":55,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" tool","obfuscation":"z3ZmQv1NXDB"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":56,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" to","obfuscation":"TKdYfVpKhKutU"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":57,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" get","obfuscation":"bo91thYZp7Es"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":58,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" the","obfuscation":"BW2g8qL8CH85"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":59,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" accurate","obfuscation":"9lc5Jgv"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":60,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" weather","obfuscation":"sInoioSz"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":61,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" information","obfuscation":"eDxt"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":62,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":".","obfuscation":"JYedg23ufi7gUtZ"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":63,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" That","obfuscation":"g1t1lfgXbYY"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":64,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" way","obfuscation":"Ep5o4rLfxcIh"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":65,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":",","obfuscation":"TFbvXNdkkPBLVr1"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":66,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" I","obfuscation":"LcYUPQWtuYhWe0"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":67,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" ensure","obfuscation":"cyf4QhE27"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":68,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" I","obfuscation":"pn0OngyYqOV7mp"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":69,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" provide","obfuscation":"A92JWktU"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":70,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" the","obfuscation":"nXnGAWZBV0kV"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":71,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" user","obfuscation":"LIgDJRJ41DB"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":72,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" with","obfuscation":"yswEW2OEdl4"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":73,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" the","obfuscation":"X9UZPFhnozCc"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":74,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" most","obfuscation":"FF37xAFgTkH"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":75,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" reliable","obfuscation":"lZjxdzk"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":76,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" data","obfuscation":"DAev8Lq7rfQ"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":77,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":"!","obfuscation":"HSi5SufVKPmqOiw"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":78,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" Let","obfuscation":"TXlmZbtPAXTO"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":79,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":"ās","obfuscation":"ZLJc4VkP0brGTz"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":80,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" move","obfuscation":"RVe9znybaPh"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":81,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" forward","obfuscation":"yrlGbQ9b"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":82,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" with","obfuscation":"4TztdxQj7As"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":83,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" that","obfuscation":"6bxCZN3vOKW"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":84,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":" step","obfuscation":"XjgzqaaY7sM"}
+
+ event: response.reasoning_summary_text.delta
+ data: {"type":"response.reasoning_summary_text.delta","sequence_number":85,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"delta":".","obfuscation":"qm9kF7pEPtNE806"}
+
+ event: response.reasoning_summary_text.done
+ data: {"type":"response.reasoning_summary_text.done","sequence_number":86,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"text":"I need to remember that the system indicates today's date as October 17, 2025. However, it seems the weather tool will return the current weather for that date, rather than needing to compute anything myself. So, Iāll just go ahead and call the tool to get the accurate weather information. That way, I ensure I provide the user with the most reliable data! Letās move forward with that step."}
+
+ event: response.reasoning_summary_part.done
+ data: {"type":"response.reasoning_summary_part.done","sequence_number":87,"item_id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","output_index":0,"summary_index":0,"part":{"type":"summary_text","text":"I need to remember that the system indicates today's date as October 17, 2025. However, it seems the weather tool will return the current weather for that date, rather than needing to compute anything myself. So, Iāll just go ahead and call the tool to get the accurate weather information. That way, I ensure I provide the user with the most reliable data! Letās move forward with that step."}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":88,"output_index":0,"item":{"id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","type":"reasoning","encrypted_content":"gAAAAABo8jmqx_GyKbRHioPoEL-6klOC5pRoqBX4gYCToNEaQc9LNoM1o07M4sIhkTEvihiIOoesa-F7MxiNod6LQde6QfWApwtdzIjNnK1zEkWI90NQACdYu6xLrT7Rpf5ejTGLlLjIFfkIn0o6RdE1e1zu_Eu8j-u7CU1QEAvcST9rK8LpSCfn-QzK4jJ0WxzUpom7G2AHv1G948BUBFgdDAianK4XURVE-kU0Aof0fAOOYzx1L7PPj9Oefq5sWcpmgReb3xjMbjnMcHu951YgQ25tiku8iarv8Iy4U02TAHzuT5kSuBWwbuKiyOc0kYSkMNJYryEDaA2ShOyDILrCCSCXWGiUq_h7FoF5vwX3drvI1Kb7A4FYBtZQyaOLjjIFVA6_0ZJZ4aqYhEn6_aq7gIjo0_A70hKuxFtTSBz5KK1sC3NANhNjVNIRZByg1WOEY6izDlcdUtyZNbQdutPV_Ow5wv2AI8TiBrFnk5RdZ18KSjCyJiTbVoxATGSwlO4246vfZJxajW40RjJKMPcEmZZJD0TEGrFe1xWIJ9pCMFXbR5bEUznw9uGHMbHlTf3GjRlcp31pOPA7YyUdP-6Zo-j9bbs60mW16Bc7SfkzJ1mzcOlkTwh0g-FTX7Ihi-6148aO1bE9FBDsR8TOZCMwXDmid2vWWdvnCW-Ez5EWPE_rKsTOboPnXM_yQZyPcwIC8a6Zo7YWi-xu8bjlguWCHEm9FcKL7m0IfmVyfW5FzhrOEycEJirwGxB5tjEvaTIYSx_mLjdZoGs8qxoRji4_V4-prgKruqtNSTTwRRdR7taIReeLQElJPNrofBNdO1PO6nx2nUfdHsD0e9RdiKtoIptc4niNl6-cfut9rBMNhtDzs0mb5oOBQfCqnccu7tgm7CUdPi8uiYvYr4u6ZA_Q6mdd-dFswhVHdMQAhQ6UtRkvS2O3XX-6C7R8-xH7IsgrBaiNB--8h89qQfbaptnHj5dv4mRyrnD1SviGwAldHZtSttZTxanxQXt-GrvL7Tk20QF6bcant0xvlZcLWJEVoVrUYgSjlCDqo_ipXIoJ1-_O6zYo-kiWHVJkEA4Se9bO7jfjXs9tsbM6ByZgNoyShqPcPqLunrGkfaEwQHl6s91wKPzTvJz5tUisXfJWDqU38Xch4tha2yTN-NfeyLsp9voLfuRHjW-Cge3I_cPR49WgthgtsmWZLJ4HKQvYruU48Asydnw5izlU9pZJo1eaTK3adjSTcLZtUGHQcCGN3455gbFuJhSH38JllGxR4yzGAxyzWtbV0mYvWRaVaSrJY_qXpc0mAzwzGoMnPOrQWtvuwqPwEFJz5bNwe4aGccePtdLaM18YkOFI-kPqDjiC8bpaxNQm_Pq2fz2RRvsySwL-N3pg32grZMTU6CcWednX-fG4SS0_-OWNPwm815zV8AcZcAlOPtIeiLBkV6xZ2D2BrQbTMfIg9zMHVS43U8e_Okicf9JhGR3ej1UrtiQ6fUsm61xsI6GWUL1z8H3e6hHmZJdQm3zx8hFgpjRhsjinndGOmarCYscraxlGAPx7XFx1dCp-_0gHjKuFp4cmbXXJm4dKWPrcTvhaMGRHf2YGTADM62oQdZvoT-PGb9e2f4wkaMZZbKv1kZsAGcbjAPGB6PNffM3rLCoJ4qkJJJtBVWP2oZLWCtSKeXpii5vQe4_D-ewtS2Dyen0USCPjPLaLVC46E5j9EmmAFsWwl0EFPziFN5tMWqiJtNQrpcWs10jlPse9FhmEeUVzSuGtmzzfdcysPsduMTlvF1BSuhtiWVYbrnJyL7hyWWgBKcBTYJokC4k2HNJjQBI1O-LKyP_yznnXPdzIFgzC3X3CmegTw1uxBFhQs2UpN-b02xgmLerFOuw-Xr1BXvLlVEALnT44yqJYgZ6eTBiMiCnXwqwHWWdoCzll_sxhuwqZDtqj_V5C9oroqNhUnfKNo2Y4ASp4fqh6AfNhZkiBSbOh8t7sjv0QMYCv84bTIt1bVaR5LMc2pJ1t9kHKTD72ey-hQZIfIpclCsfoqp9RWDLbi6-QPmmMlLzVZnx4sCrMl3W8Se0lToXc5xFwKm9sC-kaQIfhXaymGgSc4ra53yy9XBoDMYUZQhqDJwTy7QHCmXFKt3JuxsF0yqf0T1IA1vZ68DPtczKxRlBcUgXKllXH9DbZVvyoivKgKruV-QaKT5Pl4dq82JhJUAKuYMb2trxXfdAVflBNYt8-WnDjk8FAMZ8k5EDddssL9E5M_KDEN8X1HpzEwiE7KPeYXo4E6kgCqwXpIiSJ6lc=","summary":[{"type":"summary_text","text":"I need to remember that the system indicates today's date as October 17, 2025. However, it seems the weather tool will return the current weather for that date, rather than needing to compute anything myself. So, Iāll just go ahead and call the tool to get the accurate weather information. That way, I ensure I provide the user with the most reliable data! Letās move forward with that step."}]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":89,"output_index":1,"item":{"id":"fc_00564a370f8761470168f239aa85508194bd45f6a7c8b4c721","type":"function_call","status":"in_progress","arguments":"","call_id":"call_8feZLXZajk3zUG5EkKIkQlwn","name":"weather"}}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":90,"item_id":"fc_00564a370f8761470168f239aa85508194bd45f6a7c8b4c721","output_index":1,"delta":"{\"","obfuscation":"qPH2UN5JMBy1tg"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":91,"item_id":"fc_00564a370f8761470168f239aa85508194bd45f6a7c8b4c721","output_index":1,"delta":"location","obfuscation":"8o2cDMaX"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":92,"item_id":"fc_00564a370f8761470168f239aa85508194bd45f6a7c8b4c721","output_index":1,"delta":"\":\"","obfuscation":"atQHlPUQX3i0x"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":93,"item_id":"fc_00564a370f8761470168f239aa85508194bd45f6a7c8b4c721","output_index":1,"delta":"Flor","obfuscation":"FyOWJCAJ812w"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":94,"item_id":"fc_00564a370f8761470168f239aa85508194bd45f6a7c8b4c721","output_index":1,"delta":"ence","obfuscation":"LPVUL71dNKkj"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":95,"item_id":"fc_00564a370f8761470168f239aa85508194bd45f6a7c8b4c721","output_index":1,"delta":",","obfuscation":"k3kZKdaocYlen8a"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":96,"item_id":"fc_00564a370f8761470168f239aa85508194bd45f6a7c8b4c721","output_index":1,"delta":" Italy","obfuscation":"gD1hqivGgC"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":97,"item_id":"fc_00564a370f8761470168f239aa85508194bd45f6a7c8b4c721","output_index":1,"delta":"\"}","obfuscation":"HYSCdXOWhvBzKy"}
+
+ event: response.function_call_arguments.done
+ data: {"type":"response.function_call_arguments.done","sequence_number":98,"item_id":"fc_00564a370f8761470168f239aa85508194bd45f6a7c8b4c721","output_index":1,"arguments":"{\"location\":\"Florence, Italy\"}"}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":99,"output_index":1,"item":{"id":"fc_00564a370f8761470168f239aa85508194bd45f6a7c8b4c721","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence, Italy\"}","call_id":"call_8feZLXZajk3zUG5EkKIkQlwn","name":"weather"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":100,"response":{"id":"resp_00564a370f8761470168f239a3f90c819492eb21bd9b25c369","object":"response","created_at":1760704932,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[{"id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","type":"reasoning","encrypted_content":"gAAAAABo8jmq8ZgK6_R2_mBtj66EaDbh24YJ4IzeZ8ry7g2vxl6uWYZxXWaiq0s0n6ynJc10mtSY1K2nLDwlcpxs3tahcZMYiwh879zVkpQfoH4ze1LFLRQ5MYJ7R5qvj8vLVXz7rFqKbCXWSXKpbCnqyRiURV8SG9f9rRLZ30IYDJHJPsSWJVD4e-ROkag4B7TnYTsPDfzga_eKKL7yi2AmVLpetADp7l_MBaLpUeqmOUUWp5ieyLZ-b8Cu1AovW2nnh79yNw5RiBuUYZeGyIRkjbUuTEohG8t2CIL4S2cUy60kia557RDbSZ0wscjY0M6ZkPwWY1kf08OSvcbKypyDOmwZdhYH_ABgTXFUDCUvSoCGAg9OGS4kqOOePY3wgmhPBK2Ufj3a1phYY7X53Rxb90CR4oueX5JI-HjhwV6Vzx1cia9XeGCTbPuyOAcd9k62z8bCKGPd9OAxLzn63u-o_NG1GvRIFtdOqOEpFo6hpfHR81nUzporv-Tfv2SXVlo8bKSWjOrHuYE0usqRXYB3UmZxEdXHcafOVDOUjJ49JrL3uutVQWXGCQnMqhjiefwzBvIa4BeelANG6GkfNNeGyD2mf0hn_5cUd6v__umQmBXIx1NkbG2iFwtbpaOD-BSU9DMOHBJ4PqUGDT6A4geVUrXBb6NwE11JHXHPBVZMVvc2pDERJciTxNTbNpqIbHPKkKmfcXBoxGCn6LMZVZaVygaGmlkkhAf5NfS4O5hPZMFyEDA0-PYzEEZ3IRA7V1rvIgNI5zv0wC2TyENiUIHsZcOwE7mA0Wnn_uapgzC8gI-D400m-3bi2JiXij8WvEL-_t09K5O7CWcewE5yClFVHSnSrWjyYY_U87aNX4gr4zdC2PP_vRKwE9DKqUXTgQpVQ73RMuXzbn37PEpZ0rappA-5cP2mjUUrhEiXl9_Ci3CbZ6Vt7qbCGrfAVwJ_Q2m7X2M1Rbbw2--JX2FRaxpJ0Mr90StSQI8cZ1H75VZXDZoUkmQv5BT2Ek17d9D-IF258u0PHykXiP7FAi4-HMsKToO3GPHqmuUvs7TAYvNXLBCRwOzP_Fv222dCbOnj7G3NNCSTuWwanayL1j2s0wYSqee5NIBoZHv2lhQzxWyTeNT1dw5eeuaLGgaBMFfgUjmh5vOxid_ablfG1hfp_a6sZ67uwA-_V8bUA8Hir1Binez5jjEXDLWXod3cjjx48kC2CiapP47L8qaeN2XPv4EcBO-iqdenpLKTQvtgUezMP2uuuXnXR6nIhrMJH_NxGyw7dcUyIq2j-WKBDHBkwMFuG9Pzpmbgx6jFgDZF_JDjnSwWSxp-sOr3Ofhmp9Ul8uS6hZtNeaOr4uKV80XhxjDyUiZOoNgOjdzD5sJFLU_xK3Chg3A61ujkSSkU-8gWkhGEbYF_6HkshTs3M-MmTUZ3FsIjYaW5EEJLcjN8Fth82FOK-28Oactl9gl79wMMXu3ORDbySgC10VVR_TFlxYX5moKLUDh5EheNBEAHG8PscCXxj1hro3uxXgJE3S_sYm9qV3kCU5XusY6Ql9M7CimpDvvUR2yf67ijxvh5gsVdxcAfUG9su6qLoXMUshs7MYP4sraKQ0Y4Awor6GrR23R_eHpLpzdlZ-eTNleoyuwZ_KmzgmHfr1Q4K4TV6GmSqhhm16bmjbCaeUmWagy7Ng0KL9JC1zeMgag1jh5ik4kCj0PB4_Z4fDFaM8cg2jScxIFo7CAAzYS2xBFmxihuBa1iW_P7E3gQjVwZyF7Qkjyhdb5HxsIXysmHOEc3ZBNK-cwWJRHYAHqWuIJ6z2iODE-4VBy29jHfieta0FRUeeWHT5mx5UQSB87sUJpqX1U_bIi315ZmVKwChSdKxBluLHkchpYt34f5eKtFpujzwMGQmSx1_ETIVCEUJG-MluiA2rZxQvtetLsVCUGXKf5zOgduI52skT_gxwGfG5QWYYgVxHiLICgTixgkDc6hQ9AJpw3YNZBmGXNMQPof9m5cXzj9Zni2_1SOKvez4RUujpD8g2cpn3O7t7qzK_-d-u3ZMNwTE-r6xToGEarAsoPSWSeNM_FSCqqsOFvr5yQc4NgTrQuY1NT0Zn-4WCyI9svGxdi8Y1kHIirZfBABsW-dDvFlnCU-LAFhz8K_Nv9-7LZGr--qEfuT9CjBtdQa3VD0UdN84uPOi-djuCEJLjTDPvcNc9it4Tkdc2zQJA_iaJ3-pNOzEP3clK-TD-jdNA9N_9kkpDhJtaHq1iyijEKBH1IGxctQsk3EySZGO5LiAgYoRXn5b8-6-EM=","summary":[{"type":"summary_text","text":"I need to remember that the system indicates today's date as October 17, 2025. However, it seems the weather tool will return the current weather for that date, rather than needing to compute anything myself. So, Iāll just go ahead and call the tool to get the accurate weather information. That way, I ensure I provide the user with the most reliable data! Letās move forward with that step."}]},{"id":"fc_00564a370f8761470168f239aa85508194bd45f6a7c8b4c721","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence, Italy\"}","call_id":"call_8feZLXZajk3zUG5EkKIkQlwn","name":"weather"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":66,"input_tokens_details":{"cached_tokens":0},"output_tokens":214,"output_tokens_details":{"reasoning_tokens":192},"total_tokens":280},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 543.7015ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2191
+ host: ""
+ body: '{"store":false,"include":["reasoning.encrypted_content"],"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence, Italy?","type":"input_text"}],"role":"user"},{"id":"rs_00564a370f8761470168f239a4f2fc8194b38541e473cdb603","summary":[{"text":"I need to remember that the system indicates today''s date as October 17, 2025. However, it seems the weather tool will return the current weather for that date, rather than needing to compute anything myself. So, Iāll just go ahead and call the tool to get the accurate weather information. That way, I ensure I provide the user with the most reliable data! Letās move forward with that step.","type":"summary_text"}],"encrypted_content":"gAAAAABo8jmkhn3gO_TMlHP7zrmqSQK6e2YwCe3YftZKY9Y9Am0N47nufS0EOe2c40Ie_ULjJ_I4NfuJMK2z4f-hl32bIn-6n_VLQtWy0JNg5qIiYspMtmsGPDKY0PqVj8rmYPrrH6UBrnmjOIwiBy-owTkt4-iRe7p39ooEi23aAg7edh9Cus926ptNWnCyRd5LBxp_pLeUBbjcnyZKbN8sHpHkYBXi-d3tKM1w5RKtWwNk1iYZeSpMnFeu-0Rh6ybotX-rx9IRZceu-zOBPpk0Be52EqZGZNZtB7mmsfX9VainX3PHsAviBrwTJH5dSBMpRft_Mw0YE-rVBCcCRk-aDqJbxDgxndIFci_GHsu-iPuwV-kyIGiIMT_m1n_DSnQAkdY5Ur9gLMu0x91oug9mePtyoUf5SEIw4HLUVRESBhxg1pZr-QR1dv-qTjjyaJnRVQFEFcaKxUxRbKUEoMP3T1sg72LBP2kh6t9GtwNjPD5S63TjWBGogzHfOlc2WmiMzG6B0kY9xFh7wIM9XqbRvggxnNK37ltLB57lL73RckCP_4A2rLypjDmeewnDF0xLsKjVh_KHMMMrcMro__2EDnCIMpyWn5PFlEqHoAn1XcL81NSSxqgc12LYfTy4AddcrLUyNY0TDoV7J40oprdDPmD7SdTPcg9j4NXyQcDwcs_rsa_mtY4XH--Qd7EdCCOETDAaHi8uzz1Ig1gHGE-2sivK_NCqIUjX9IifDBZ_EycsiRhvoqKK58aE6ZxAKMzuvQZSGid9avuGUzO_bSvuCLVfYMeLsR2twj__CX6yXLvkHy3WebfqsABEFbklAp1A3ZAn17FJ","type":"reasoning"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_8feZLXZajk3zUG5EkKIkQlwn","name":"weather","type":"function_call"},{"call_id":"call_8feZLXZajk3zUG5EkKIkQlwn","output":"40 C","type":"function_call_output"}],"model":"gpt-5","reasoning":{"effort":"high","summary":"auto"},"tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_00564a370f8761470168f239aaf05c8194ae07775650318b6e","object":"response","created_at":1760704939,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_00564a370f8761470168f239aaf05c8194ae07775650318b6e","object":"response","created_at":1760704939,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":"Current","logprobs":[],"obfuscation":"AUMGN5Q3K"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" weather","logprobs":[],"obfuscation":"qLtTyxtr"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"C66nAujPIMzSS"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" Florence","logprobs":[],"obfuscation":"SnIKR03"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"UUiwNeLx1iroF0t"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" Italy","logprobs":[],"obfuscation":"SuLohkrWW7"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":":","logprobs":[],"obfuscation":"2cSrgMrh5XW968L"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"SAQ3ByVC4tefn76"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":"40","logprobs":[],"obfuscation":"umc9EEXQok47sF"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":"°C","logprobs":[],"obfuscation":"NuJ1Rz9JIahUu2"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":".\n\n","logprobs":[],"obfuscation":"amqhasz75jUjb"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":"If","logprobs":[],"obfuscation":"04w1vFvjNUodA8"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" you","logprobs":[],"obfuscation":"oMzpQiGKAyFs"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" want","logprobs":[],"obfuscation":"E1O6WPWxSO0"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" more","logprobs":[],"obfuscation":"kxFb99oWpSs"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" details","logprobs":[],"obfuscation":"J3UJtyM5"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" (","logprobs":[],"obfuscation":"9iydpihu9hCwNH"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":"humidity","logprobs":[],"obfuscation":"DVhtywjq"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"d0ehS04wmj1oojH"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" wind","logprobs":[],"obfuscation":"HgSFvj4A844"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"AJkG4jtxZIlaBHM"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" forecast","logprobs":[],"obfuscation":"VLqVo3G"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":"),","logprobs":[],"obfuscation":"s9Bj6OgwIIDG8S"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" tell","logprobs":[],"obfuscation":"THWK3ZVjtpB"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" me","logprobs":[],"obfuscation":"Zk9eOpTLijZxG"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":29,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"O2NrpsXiaxeW"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":30,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" timeframe","logprobs":[],"obfuscation":"NoqO6v"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":31,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"of77Q2mtoqU81"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":32,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" if","logprobs":[],"obfuscation":"IHhYXuUnYAjr2"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":33,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" you","logprobs":[],"obfuscation":"K97GCaBS1Brl"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":34,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":"ād","logprobs":[],"obfuscation":"hb5TGRL7gboaIR"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":35,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" like","logprobs":[],"obfuscation":"YgNGCMS7ROq"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":36,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" a","logprobs":[],"obfuscation":"XlQDpZWGWK97Y4"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":37,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" multi","logprobs":[],"obfuscation":"V9W0gT0VFQ"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":38,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":"-day","logprobs":[],"obfuscation":"NGHw8w8mjRsX"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":39,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":" outlook","logprobs":[],"obfuscation":"sQ1V9LLI"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":40,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"i7Z0ECrIuVBjuoj"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":41,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"text":"Current weather in Florence, Italy: 40°C.\n\nIf you want more details (humidity, wind, forecast), tell me the timeframe or if youād like a multi-day outlook.","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":42,"item_id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"Current weather in Florence, Italy: 40°C.\n\nIf you want more details (humidity, wind, forecast), tell me the timeframe or if youād like a multi-day outlook."}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":43,"output_index":0,"item":{"id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"Current weather in Florence, Italy: 40°C.\n\nIf you want more details (humidity, wind, forecast), tell me the timeframe or if youād like a multi-day outlook."}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":44,"response":{"id":"resp_00564a370f8761470168f239aaf05c8194ae07775650318b6e","object":"response","created_at":1760704939,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[{"id":"msg_00564a370f8761470168f239ac082c8194bbbce632ff854fe4","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"Current weather in Florence, Italy: 40°C.\n\nIf you want more details (humidity, wind, forecast), tell me the timeframe or if youād like a multi-day outlook."}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":102,"input_tokens_details":{"cached_tokens":0},"output_tokens":41,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":143},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 672.35975ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesWithSummaryThinking/openai-gpt-5/thinking.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesWithSummaryThinking/openai-gpt-5/thinking.yaml
new file mode 100644
index 000000000..da73e3223
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesWithSummaryThinking/openai-gpt-5/thinking.yaml
@@ -0,0 +1,259 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 551
+ host: ""
+ body: '{"store":false,"include":["reasoning.encrypted_content"],"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence, Italy?","type":"input_text"}],"role":"user"}],"model":"gpt-5","reasoning":{"effort":"high","summary":"auto"},"tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_0e319212d3811f510168f2398edbc8819eb99fffb643dfa9c3",
+ "object": "response",
+ "created_at": 1760704910,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": null,
+ "max_tool_calls": null,
+ "model": "gpt-5-2025-08-07",
+ "output": [
+ {
+ "id": "rs_0e319212d3811f510168f2398f6140819ea426c36bb590abee",
+ "type": "reasoning",
+ "encrypted_content": "gAAAAABo8jmTBMurhS5oD-Y9cDAXlL496L8UQyznDBzW9nwpQfBEnXbCOU4m1NyS9wv5Q_u9-SJm8ge9KDN9YlxMjN9baf9xqGpkw3dNWkKNUgfB67evsG4asEPE6ODvJ2w8MfWiJyZNsGE414425cTxLw3RXBo5dQmx7gIsNj1XZoSRg8JOmxC9Wh2LeihVVY-_ilKi7-YrThT5KDGSJcHmCcT6gC-rIYX7XYjvBBsY3APQLEcGnRdGsWjIwUKVOZxyNMXUCTHkCHyBqnKRKkW_SIS2uuH-7qsFQ3Lx99vq6nRRxFsI9ITq3sYCPFAMYCNCguSVoXFNkB-xAMKczdtT9EKtocr781FYNgTWWC2SIu-ieuKqELsJ2JG46S04gEEhy4o5aDJ3qG3U57QSYOeNLXy9ePccJkMb0pzLwTCdVJy2Qbm4NVUk5976LEvgFV7dkZAsB4Gt3XPOUQT0pBAqOEwisubWMHn1JVdw0al0gyGzmXwYoxsJnPh3JLjsCsY2f4EyN-i41cMx3EzDEMEWiQxHT5BxYDRTAXg92L9Ryz1tyqrTZ29nxrcylvRB0lwa-zogOF_G4eTmxNfni3NeWAm1qlrO6ghO2xppEtp3w4dY--U-ZsV-WDMScu10TfBYyqw5MCgsUepm7zS6Vhoj4g7c17y-ebmhSOWX06pZQdlWJ1yBwiFs_rZ6Ta_1er5I7iQsHuTlfEdP55Eu3kOPmyoMfVyDZuFafGK4LwY2dgQtSoz3OpRZA4UGSJojD6tqmbK6HMmuVhgNqDMfGv7UfMJrURdoZiIQYo2qy556IgKckcXvJGLdWtsv-93Hef1uYSskR_P87E9FJv8mzZh0Lfh2aRRtqrG-wQKkMxesKLR8GeJKwhckJU9Rv__659Ci2LfOTIWAHHNZyKcZWiKqInUjkCvAXHzWUgxgP-RNMOEqstH10rvpf1UMpAKlGh47E1Ojo3sbCuO15FeYgiytOTo7KXMHDbcNI6CaHKiaq_QDhhstaelipfsNfvuPqaoU4suZ8-C1lYZzGK96yAuJzSbtdBxRkeMvlb0U71RBtOhPSG3YfPZ28W8kd17_iGUzskubjTSZUfSFlednoiRYOzDaMHV2uhbZhf160gxVKD4kSpZBfBZC4N4fVSoT8YtQwY91P1im6TVogfb1KwCoRPA-gk92-3fDPs2Vf7l1qKGGYR-6E35OG1Lbi5ni64Bjq-0rpNpJmw4wKQrgZYygbhLpL7e0UwJA71JQVtSb65AAc_Jxmk6MPiCakiUCrBD7ehtr3jv-E12XkybUiRbTFEcKEn-cIgbOhNgFo8ZHEjImnbpdMN9b8zrSjfWJ86sf7rpKrNf8l6EX-65Y2rdhrb_0feo0t9jbEuB9xkSa8e6Ldk1Il4dHIEpMpwwreeft7ozkqDzC87j97UTp4fXsXb6Aoh_Bb9OzMYK3f8Bxb5w6iu40u6JYAp4kNmFfPFWGfp4IDCun9RfM-elaqOD14VMnvOW-PyiMZrAgw4MQ9oRqeXU0TNRKKMtSyPPeGFeIsdBV8I23w0F0MdjeAqGnsYCiNpSPX3DxC5s7oQWfP92UDrsu9NwpGvyF6be9bP0lrBM-D0Xo3_T7LGznO71xytuLFA9tnUX0bw04SUvf2xdt5-teNooXaivERLiwlL_BCxZlN0A7TEo0LA6XnqEWR1LoifhHrb5KJCSzrkyFSNi6Rz3tyoLKKiERbY56PCZKcE255u3cLBf2NhN0ErR3K2DzOf6LHmsnrnG1S_BV61LZKlio7qQC_U0SvB_sP529mOCXGQ5JQ8YrXQ-M3mdkbAqsV0EF8QQ9qIxa0wiAa1eJ-u4GkdTy5jAYaEIRCXWCwP9NH0ho",
+ "summary": [
+ {
+ "type": "summary_text",
+ "text": "**Fetching weather for Florence**\n\nI need to answer the question about the weather in Florence, Italy. There's a weather tool available in the functions namespace, and since we only need one call, I'll use it directly. I'll request the current weather with the location specified as \"Florence, Italy.\" It's important to keep in mind that I\u2019ll need to provide a concise summary of the results, including details like temperature and conditions while keeping formatting minimal. Let\u2019s get that information!"
+ }
+ ]
+ },
+ {
+ "id": "fc_0e319212d3811f510168f239938014819eaa6a95792d6049d6",
+ "type": "function_call",
+ "status": "completed",
+ "arguments": "{\"location\":\"Florence, Italy\"}",
+ "call_id": "call_NBDHXdWp4Qr78bSaUnyNgsh8",
+ "name": "weather"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "high",
+ "summary": "detailed"
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 66,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 150,
+ "output_tokens_details": {
+ "reasoning_tokens": 128
+ },
+ "total_tokens": 216
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 5.100496208s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 3317
+ host: ""
+ body: '{"store":false,"include":["reasoning.encrypted_content"],"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence, Italy?","type":"input_text"}],"role":"user"},{"id":"rs_0e319212d3811f510168f2398f6140819ea426c36bb590abee","summary":[{"text":"**Fetching weather for Florence**\n\nI need to answer the question about the weather in Florence, Italy. There''s a weather tool available in the functions namespace, and since we only need one call, I''ll use it directly. I''ll request the current weather with the location specified as \"Florence, Italy.\" It''s important to keep in mind that Iāll need to provide a concise summary of the results, including details like temperature and conditions while keeping formatting minimal. Letās get that information!","type":"summary_text"}],"encrypted_content":"gAAAAABo8jmTBMurhS5oD-Y9cDAXlL496L8UQyznDBzW9nwpQfBEnXbCOU4m1NyS9wv5Q_u9-SJm8ge9KDN9YlxMjN9baf9xqGpkw3dNWkKNUgfB67evsG4asEPE6ODvJ2w8MfWiJyZNsGE414425cTxLw3RXBo5dQmx7gIsNj1XZoSRg8JOmxC9Wh2LeihVVY-_ilKi7-YrThT5KDGSJcHmCcT6gC-rIYX7XYjvBBsY3APQLEcGnRdGsWjIwUKVOZxyNMXUCTHkCHyBqnKRKkW_SIS2uuH-7qsFQ3Lx99vq6nRRxFsI9ITq3sYCPFAMYCNCguSVoXFNkB-xAMKczdtT9EKtocr781FYNgTWWC2SIu-ieuKqELsJ2JG46S04gEEhy4o5aDJ3qG3U57QSYOeNLXy9ePccJkMb0pzLwTCdVJy2Qbm4NVUk5976LEvgFV7dkZAsB4Gt3XPOUQT0pBAqOEwisubWMHn1JVdw0al0gyGzmXwYoxsJnPh3JLjsCsY2f4EyN-i41cMx3EzDEMEWiQxHT5BxYDRTAXg92L9Ryz1tyqrTZ29nxrcylvRB0lwa-zogOF_G4eTmxNfni3NeWAm1qlrO6ghO2xppEtp3w4dY--U-ZsV-WDMScu10TfBYyqw5MCgsUepm7zS6Vhoj4g7c17y-ebmhSOWX06pZQdlWJ1yBwiFs_rZ6Ta_1er5I7iQsHuTlfEdP55Eu3kOPmyoMfVyDZuFafGK4LwY2dgQtSoz3OpRZA4UGSJojD6tqmbK6HMmuVhgNqDMfGv7UfMJrURdoZiIQYo2qy556IgKckcXvJGLdWtsv-93Hef1uYSskR_P87E9FJv8mzZh0Lfh2aRRtqrG-wQKkMxesKLR8GeJKwhckJU9Rv__659Ci2LfOTIWAHHNZyKcZWiKqInUjkCvAXHzWUgxgP-RNMOEqstH10rvpf1UMpAKlGh47E1Ojo3sbCuO15FeYgiytOTo7KXMHDbcNI6CaHKiaq_QDhhstaelipfsNfvuPqaoU4suZ8-C1lYZzGK96yAuJzSbtdBxRkeMvlb0U71RBtOhPSG3YfPZ28W8kd17_iGUzskubjTSZUfSFlednoiRYOzDaMHV2uhbZhf160gxVKD4kSpZBfBZC4N4fVSoT8YtQwY91P1im6TVogfb1KwCoRPA-gk92-3fDPs2Vf7l1qKGGYR-6E35OG1Lbi5ni64Bjq-0rpNpJmw4wKQrgZYygbhLpL7e0UwJA71JQVtSb65AAc_Jxmk6MPiCakiUCrBD7ehtr3jv-E12XkybUiRbTFEcKEn-cIgbOhNgFo8ZHEjImnbpdMN9b8zrSjfWJ86sf7rpKrNf8l6EX-65Y2rdhrb_0feo0t9jbEuB9xkSa8e6Ldk1Il4dHIEpMpwwreeft7ozkqDzC87j97UTp4fXsXb6Aoh_Bb9OzMYK3f8Bxb5w6iu40u6JYAp4kNmFfPFWGfp4IDCun9RfM-elaqOD14VMnvOW-PyiMZrAgw4MQ9oRqeXU0TNRKKMtSyPPeGFeIsdBV8I23w0F0MdjeAqGnsYCiNpSPX3DxC5s7oQWfP92UDrsu9NwpGvyF6be9bP0lrBM-D0Xo3_T7LGznO71xytuLFA9tnUX0bw04SUvf2xdt5-teNooXaivERLiwlL_BCxZlN0A7TEo0LA6XnqEWR1LoifhHrb5KJCSzrkyFSNi6Rz3tyoLKKiERbY56PCZKcE255u3cLBf2NhN0ErR3K2DzOf6LHmsnrnG1S_BV61LZKlio7qQC_U0SvB_sP529mOCXGQ5JQ8YrXQ-M3mdkbAqsV0EF8QQ9qIxa0wiAa1eJ-u4GkdTy5jAYaEIRCXWCwP9NH0ho","type":"reasoning"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_NBDHXdWp4Qr78bSaUnyNgsh8","name":"weather","type":"function_call"},{"call_id":"call_NBDHXdWp4Qr78bSaUnyNgsh8","output":"40 C","type":"function_call_output"}],"model":"gpt-5","reasoning":{"effort":"high","summary":"auto"},"tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_0e319212d3811f510168f23993d900819e8554549fa904f584",
+ "object": "response",
+ "created_at": 1760704916,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": null,
+ "max_tool_calls": null,
+ "model": "gpt-5-2025-08-07",
+ "output": [
+ {
+ "id": "rs_0e319212d3811f510168f23994f608819eb5076ad513ad1579",
+ "type": "reasoning",
+ "encrypted_content": "gAAAAABo8jmjstHHULLsMGxy2E3-Xo0O0cUVNx6b8OSavmNWeweibhRqRuP7buLPHMcHqUXWMBtPsr5yH8B-jgFp1pOlLqCMYqu-_Zs7Y0i_vbCM6Qt0uimhYDddVqAw5Fy59--GAHN96mZOeIn0wfxfTqemDmMl1B2YpyM9uly7eQOUsja8oXMvb9ITk8r2DvQYPJ0L0JKxLV-_xC-bdb2GFJxv1eQ6kaHGvsozk5noabtZ9p0Ebj0_WHdtDqmU6RCsyaDWC3JvSEsJiJN2bVkWHu6MN71ufXGZUn6_m4_-8TiUVFQHNP-3iqbnn5gjt9MTunXDbjRGbgOifw8H7FXnW2n41lCF7N3eA59gcQ1rljRzCZtcrLZzW8UV0NWO74opKQOKn8e1En76A6kWVaDspeCQoFFWv-aYWY6i9CoBCerp_zKYbwEyqRgdj-lGg94R3KVGvVilAU2LwRt4btMU7HeeITiRObvcfxxiNGfr1ymt1bwo5aapEDMaf9Ahx16Aq_hE_AGLP_zSwpydNbLGeBSmXjDszP7BjFcsvkacVAZJjD4d2eaNg994g_kuqGmcinoKMJDPL4oskQidWG-KWBmb76Gr8kR8497T3j9X1PwRjKt24hDQGhuGB_EPUtVZpXOxrwSFeogPKJKK2sYIT8Z6_HpJfCchzxVHPpOt8n3GWpy3OvDkE21ZHXPt-d_EWRltCE_PUndIrGDcmj-7Wf4vV_Y_c3OKFNv_9jPIzMniYf-RfLCCkVR26lmZ8KRaqv7ijaTiqqiZ6MfG2YCBhMOeyb-3ZLYkJvd0neY6PZdx2v36TkVhdt545BCyB07ZPzrghYe2sJENnvzie5nc7yn5eDWkT6G7z0KI_6LcG2bGnlTEj2NnJ8SZORO0DY3DNd9j9M84emBySsnLQoEEGjfIpgR2FB_8M1XvN2JQM17m3R4rth-XsWToVJikou6VPV7eho39qnEsiUoksPgsElFoXC1ChXgJA64uuoPQ52zf-y4ctjayMDfyTUikOCDO64j3xT1xxKI4N6m25pzC__b7urRIUOxHd2MrrGaVMax9Tmep3NHwuWa9Zsa0-QDSW0fNOxCV5xcFczkSZxyA01UdiV-6wsFAn_Bjstd2F4kIPLcwpO7yYJUI806VlghIH0LZbQfbGuAkm3b9Pi424KVV9v1UcJ3vxD8c0-D9vu0qGxmXeS0UqF0VhxDZYwj2kVoINHZUf8OEZNnfuWNicbjjBGRjH_iYvrl0iQ3kdu6apBJuY27s7rv5ShqXSdUjMdIeAj7AznPVRB3w-tSW1Yg7pAUIjogr2BfmifBSy7sZA1ePjTRQnXb9-7x7z4fLs0FkatnRAaOnulb2X0sRucI38CZz6j8RuJomuSkI7LF7W5jKFHcaOe0N0kI0777XDFeDop66K5EN83MJ6jG3U4Fh8Fe-TtoTmuMHrs-zAo6u_8OgcsblF4YBc1Re-X0s9q2KSpLIie4z1sA0Cu6-PAPK12cu0aywx7hWe9Xk4tGkKJa2OAzJCUw0ResTn4By2iQxcLHMviw17J-M5ti4uZT7lLu2vNa_fJit2oB9pAN4uEvNHEN28HDK_xm_vJO1G-Mo8pDEOK4kR2SYMUOIq7HrtANeh5q-4IONCtDH_tC94xJxphnXO7Wo4oo9_iv88s6-BM614L_SHL0-sfU8ud26td__zDrVI5HM7-RsoyTFcovUA1SqtF0sfs2WNuCrImEy6Od0sneYzAbrHbdHiq7UL-qnohYSf-ki9PJ6yUrtrNQ9HT5J0dpVDjKRwoAt2g5cYRhxVBzc7zY6_amRwn4RI9oJNvYah8hiQlKaTRaLiuqqTGTKVxU3phLU5oSR9aWlk-Cqp0Fm1tdAQ8mSjC_VLWCZ8EyNIrt8FWfub6pQecfH9FJ2Tdd-2cwFGstI7YXTRiiFHHPluR8VYnRPySS6SEfQH-g3cUgMybM4BkzEbhf9Fqa-btIWfAItNQsZ63Lgd8xUab3Dd8N0BijFdBWC3N7jMg3rzJwqH3KFPiBClWQaOy9f5vim05Wd-TnUb1_PtYxTyDbSCy0fb9AJBZOGcHyg_VTuAGPjvE6AeQSUXixSWwALyTsGQUKqGKo-sltdenOR3fmwQsTZ3w1EAh5qrVnnpfDf2I1PkSKWG6SS7VmYmS3cf7RkzNm73ZBKZPBEFRNI5X1ZnZ5lt5CjGMSQJN63bGqAjuEYG7DJhRJJf9shh5afz4Jp3zbvaYxnnUVpXkm5FPdksn3KEq-DDOOD59dwoetWCzaNw44nY8ndpUiNn_dwtQb7VEQz55h5tc0NaPBaIaUTlMoPnEKOLnKEb5AgCNwSR9hu6fMRGucSrnoh3IBJhw_aP4pUyfJEMRqQsHG-H6kvjfVQogWDw0utrHSaWmubfpnmIKgbKIFNC0IP1ubTxPok9LQoHRwotesZ6FjneMfN_EGunqT6XhzTsU6SGW1fx_ov0NLN4o2ifovbc0hoTdZMedYvomGzY5Mw4euVEzbSNPlmGHU2ATXW9bb0uDM2TtCRVX2Hldy2ZJS6P_gxovrofW1u9Wb9Bv8K1jW4W5zKr_24UCGWfZoq5Th5qDoNB_iskRyBAlMRtFSXhmH7RPunaGjep3aV9r5L_gnfJaMS4MZmRdEU4YOxKevHoSvnxAGYJWh4sp4z87IczKoFi2uWDQtgOkKdP8RDbKjc_henAHcsJnDKfnnIrsWvrIuzpjGLrtQuAA3Dj28AaxbNw1K_wtTZFjaThRF7firN1LEn6WxCBAblULVwOEPJmf01vIVXGI4Me-ID57AgTEf9nBm7TeWDLLhAcWBWNepchyhIxiFjKS4wmzePThI6bf0Ny9TvD85kXG2LG8dl0v2cNo9k2yP7emoxbOHkATVkPxYBblIciIl3bzbTNCSL63K_2uu7sLJo1OXAYWqfzB2iIiTmKGvkd4PQdpiDdpYAGVWUBX5mf94sRryFIGkmGw7qKb7tyHcdh5Ox1hkaR8RUFCYit9lgTW883KxrbZoriWDhOEP_EPmdkBa6NRyEHP_jXL7lk_XO07C1vjtchS6CagBGh_yGOaL_plSNQ08sE127DtsQrnxnTFFxD5slH34NxHSShGRwonaNafyquj1z_D0ajQG1mD9LUz6d_Jdr6OvqsV7Mr5x5XiA_-Gp0MGreWK_vgRlsxDQnWTVC19EXWiliG3BGjW19z_7mwfwqYXO12lYq608pGLlPj7SK3US8PNVaS8CgiIzHHo95mFUfiRFHv1gguCuGRwMKQKUxpUC7XfvPabxGKHfo2ipHfVfiYNxz-78lpF5h3L3LAvBRCxSOd7iVaXFf6xn-wffhvfx4oIkW1lwZdMTASG1o5mixSQ38GRmg6cs8piag6h8BsDkhKWdr5w6WML6dlSQwQCjR6trVRJygUaOSP3ibyNrVt7TMY-gM60gtQkJVgXQHkJt5jK7lMJNQ18ODYRugXU3dbwliXGIKxFiEfie_Sm_U2FXTN-Ai16a_V5-xEidZC8y0WHpvfqQiBQbUcXYXBRsFnGpflsAccY5aP94R_2Dql40ZqfJ9bMPoXYI4eTkoUXqWTYh_u7ePFRaKsoDxsYKt0kJ4FLD5YWkRQYXLwZVTYtQOdMc6hnTqJSoJ6rPc8ag-z3eFJhenwwrtOee1q7vwJvQ-iEfcyM72NIraXHVR5TGNR359rWVCtl1jXagqGxdOfJP3b_yeZ7IBEX2dL2CR2NoOp3CN0KGimELQEXx7jtoOzHzL5JK3hI_FocKLivAYbWv-InE7vRsXfFGGOIuEDp1ErPtQ8hpQV5FB8TJzPmhjMEH_btjArfiHt1h8okUmperS-P2XCgAukmJUSRgFp-65q1noZjx1WgQJjSGm9dSVFcd7deepR2yS1HLG3UJNTUj0SmWUuWIowTWyY5ICr4ps5nuvqF4xKNZ4liSaBqKtQluc65ICFOhC4Mdt3JzxsYdA7uurIHg7PPmxSX2zYT_egt1PPl2GcqjEiA==",
+ "summary": [
+ {
+ "type": "summary_text",
+ "text": "**Interpreting weather data**\n\nThe tool returned just \"40 C,\" which feels quite minimal. It lacks details like conditions, so I'll say: \"Currently around 40\u00b0C in Florence, Italy.\" I wonder if I should mention hydration since it\u2019s so hot. The user's question was clear, and they might expect more info. I shouldn't invent details, so I\u2019ll keep it concise and offer to check for more specifics if needed. My final output will be: \"It's 40\u00b0C in Florence, Italy right now.\""
+ },
+ {
+ "type": "summary_text",
+ "text": "**Providing weather details**\n\nI\u2019m considering whether to offer more weather details like the forecast, wind, and humidity. Including a temperature conversion to Fahrenheit seems helpful, so let's convert 40\u00b0C. The calculation shows that 40\u00b0C equals 104\u00b0F. I should phrase my response clearly: \"Currently, it's 40\u00b0C (104\u00b0F) in Florence.\" I also want to keep it minimal, maybe just one line, and follow up with a question about whether the user would like more details. Keeping it concise is key!"
+ },
+ {
+ "type": "summary_text",
+ "text": "**Creating a concise weather response**\n\nI need to keep the formatting light, so I propose this output: \"Florence, Italy: 40\u00b0C (104\u00b0F) right now. Want the forecast or details like wind and humidity?\" Timezone disclaimers aren\u2019t necessary here. I could also suggest heat safety, but let's keep it minimal, just one short sentence is best. Since the tool only returned \"40\u00b0C,\" my final phrasing would be: \"Right now in Florence, Italy, it's about 40\u00b0C (104\u00b0F). Want the forecast or more details?\" That feels concise and clear!"
+ }
+ ]
+ },
+ {
+ "id": "msg_0e319212d3811f510168f239a37318819e83590ffd0bf41e31",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "Right now in Florence, Italy it\u2019s about 40\u00b0C (104\u00b0F). Want the forecast or details like wind and humidity?"
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "high",
+ "summary": "detailed"
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 261,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 544,
+ "output_tokens_details": {
+ "reasoning_tokens": 512
+ },
+ "total_tokens": 805
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 16.104320209s
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesWithSummaryThinking/openai-o4-mini/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesWithSummaryThinking/openai-o4-mini/thinking-streaming.yaml
new file mode 100644
index 000000000..897d16651
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesWithSummaryThinking/openai-o4-mini/thinking-streaming.yaml
@@ -0,0 +1,232 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 567
+ host: ""
+ body: '{"store":false,"include":["reasoning.encrypted_content"],"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence, Italy?","type":"input_text"}],"role":"user"}],"model":"o4-mini","reasoning":{"effort":"high","summary":"auto"},"tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0d54375cbcd869820168f239bca94c819cb1dd488b92e67279","object":"response","created_at":1760704956,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0d54375cbcd869820168f239bca94c819cb1dd488b92e67279","object":"response","created_at":1760704956,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_0d54375cbcd869820168f239bd1e6c819cb857543cb0e2660c","type":"reasoning","encrypted_content":"gAAAAABo8jm966Ab9kxmDUu8vgpyqAPTcdexRXmAuzGq9I98ODGUbEphdXO5ikWTpzGh9YeGP_IkNo-9JsD1yJGbxWtqOGdDjTEs3QmNHUfa3UR-xqTzcjOvmq3thRE2DEQ5_-EXkPfYSAHkPn5lQXBECz6vkzRsncSK1EcTyGDrVXvnkRpiMdD3BWeA7wofiiZzcyk7j5R-BzDWH3TUE2ix3kqzCBY7dQJDHaLCqv-SSiIcmvqYNOxPmujSY_6O0PqJ6Ze5VzFs9pX3RLL2akYYKMjJF4gb6u7S_ZHKzjWWJcuywcn6t_b3l_PF3SL2MKPZLEGbHWIp8fCMo2FJbmHyJTI102X8rTLikr4qStE6oF0PzEHsbqrgXXE8BYDgGjF5dUbn_3Hm9yDJUWqZ4qoo8RuKLgBweNkaFOU_M3GC5vWHVSaAp5vNTwXZoWHm4sEa1Hp8tORuPFn-_Y-Tp6BuFViCZ86K9QIUcVRaTGYH_yFyqIKV7FhpQIbnp1p7GOEHUQksfk29ZlboKbylbOpTlt5sqgLY_MPUUiwJortZHikNr596BBhrGgylHBq57FK3hkIGYqBQ0XZQ9WT5jhNP3NmUDdjwNRfuh_nOGeRcXyP2otI9Cu_iWJF9lUBi4-1iwwEiTFrFc62WNGubgvYSd6nf4DcdDiO5VebGSrkdDKNt2lfV99wtHiVykHMtt6eNosHMdnmK1AVBNQhqEP94J-DnYEQeNgTzRsAUgjhiVG0UC5Gep5kYRA5oKlGZxIrmL9DD8kyCO7ASWltyv4y5sczvkQjS0LlulePcPPDofKaLZV8BzD7_alBKyeg1DrTxK0TRJWEP","summary":[]}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_0d54375cbcd869820168f239bd1e6c819cb857543cb0e2660c","type":"reasoning","encrypted_content":"gAAAAABo8jm_BRor21c1_tpxofq0vEOt2hnSz-KCJ6Opk0hPwYerfQOLqqDHRdvwI3i3kLTktso_kTh_2aTATZ8AOH05mJb_FjIjolDK8B4Rn8S4FAaM-nDjjBhiewwF_ssPYQiYSIS77kTHBCbhLFtQ5ke8EIk3Srnqj7QQoq3ibgxMpqsPcvQL1M5o4k2Iuk5wAc7TrQJVhowa4fXZom_UVcRk2k4TSMshd53M9vfINB5usceSHnhuUameDySH2OAMNGzL1WTnCHnoPz4pXbBRbaFRThkBwWJbFr3me-WYbXdf1w3c-HgcgdPcKu77yuqqIEn6Y4nD_G7duS9aRNZemTUp3azMxdXXROGHTRnlCJhsrlu3UNyagxF0kWq5nvDPBA_Fc_EUOkK9TOS4pzxow001dwlkfvCSH-aoeTGqL3WBtMs2uvWpR_z_jZ4X4uX4OdiCUNcSTJ5BNUB6A3r8K1XcFLDqbOXDcbnpz04d_loHMWmwcHLr2sXuKvAdc6t3LTxnprsyMCbkuBSNljvaLWD3BMot1v0tTkpuhYnafqCt9IM2OPVoVUcRewiuCHe9XDsiahpou2Q2vnJjbcOSZOjJDbpQQBnZ5ITsVz1ZkQTPL8LOQROfsN04q4PRIIQgd8qLcdl2NSO8UqYK6dQmyLbx26Qk07X3Q7nWamBPaaxRjjvryqgminDl6Cd-Hw-pMaWlwMxaeDZnrBLm6fVWFQJ71LE_2InuuZJoqcxYaaYsaeMAcWIaRrvjyL_7-F3YNDV4mSwfzmGr_XcE1DAX73l6OcwjLMMEQifxC-cl6xxFSXno5oXCKFiKDy_GFE52KXAahkORqpilPyALeE6H8VDnvOze-pWVUDaPBuWg3PcpIrmv56jcxf2VOIgyH2TweXzxwuZo4DIGKs3cTlc2xeWQhWtBOYPRMNx0RujyheKg1wygRMAiYrBWksSfXJWdWSjmjiXDOfIbYpscdZRpJK3rVs2zWbaPhpQasuLCHpama25lvCCHPqyGB5MVzaavk-17qqhBOejF7qbnfHcE6XpWWYQuOxNXffD-7a-3_p9Gljp8mzGHZl06o1_SE18eQU30ViNDQMnilAlQvcr99w7eBhlRRacUfdqkYdfbuQckZh5Q9Mo61nARmAtRtxNrJvmTr2K67QPehOd2i7whVWN02bRvKu_AuWCbJzwFD-x81p3K9tOdxND3blvq0PBCWWAPnYc4E8hMQcOrnU9te9zmfRDyJpt2dPYO2S1s_fXAjxPdeuMNe3gHGtbrnedbv7lXhgyR5Lka0Pn1lw0iGusfXW_kg4x7yW9y928GBLFpdMEjBgbsH8Mtddh8bjIyMKOjKoH1ZnoMikkm4A5C4CdSgSfj4UFeFE5teBLT4Gm0Pt2GFtjE8hs6fpEA5eaE2YG7U9Vz7TaxJQ90k2B2p9GmUInojbjQG4T6ZKxr7vHB62QsK_GA_NLINY9gIEzO_qrjqOayXmnm3fnhCXt7DYAG2FdQ5Ujbkaq5a5XlmKIFylV-1vqkZ77K7VbWxOf2ZW064-_onREmRQOU9IhjDzQ8M_bmOHWZkbZP-_a7Tj_fSbb_pFKfpEdG3DXAOrnA69yYfJuNx-TboGuca_EeNvZQlxkNjw9ufVCYgAHCo76-Vn9sjzXd51gM2YutpGondKE-as3L0a2PU46kQGI0LS-54v2ZLVhKx-qfIVzxLTV4dKOfzQZ9Cxpw1ce3mlo1QAPLm3W4pYCuuMbW2U1jBmcnzTTI39fiG5adZ8HC1CzoaUBKTd5E4vIId4Sidmif7QOVxw1bDegdRbuA51ft2irW1O0X8w==","summary":[]}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"fc_0d54375cbcd869820168f239bf07c8819c860ab0101d690dd0","type":"function_call","status":"in_progress","arguments":"","call_id":"call_xtoGn5KFzCOsLyeQv0INLRP3","name":"weather"}}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":5,"item_id":"fc_0d54375cbcd869820168f239bf07c8819c860ab0101d690dd0","output_index":1,"delta":"{\"","obfuscation":"7BtlAO7Mx2o6Z6"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":6,"item_id":"fc_0d54375cbcd869820168f239bf07c8819c860ab0101d690dd0","output_index":1,"delta":"location","obfuscation":"WF29iSKj"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":7,"item_id":"fc_0d54375cbcd869820168f239bf07c8819c860ab0101d690dd0","output_index":1,"delta":"\":\"","obfuscation":"6ZfrxGCQGengB"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":8,"item_id":"fc_0d54375cbcd869820168f239bf07c8819c860ab0101d690dd0","output_index":1,"delta":"Flor","obfuscation":"5kXd27iNahFd"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":9,"item_id":"fc_0d54375cbcd869820168f239bf07c8819c860ab0101d690dd0","output_index":1,"delta":"ence","obfuscation":"XWKU2l3KEWcH"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":10,"item_id":"fc_0d54375cbcd869820168f239bf07c8819c860ab0101d690dd0","output_index":1,"delta":",","obfuscation":"GY2UWsg8JTCe0zY"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":11,"item_id":"fc_0d54375cbcd869820168f239bf07c8819c860ab0101d690dd0","output_index":1,"delta":" Italy","obfuscation":"SOOx4hbvX7"}
+
+ event: response.function_call_arguments.delta
+ data: {"type":"response.function_call_arguments.delta","sequence_number":12,"item_id":"fc_0d54375cbcd869820168f239bf07c8819c860ab0101d690dd0","output_index":1,"delta":"\"}","obfuscation":"XHTX3DFoWYoYuA"}
+
+ event: response.function_call_arguments.done
+ data: {"type":"response.function_call_arguments.done","sequence_number":13,"item_id":"fc_0d54375cbcd869820168f239bf07c8819c860ab0101d690dd0","output_index":1,"arguments":"{\"location\":\"Florence, Italy\"}"}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":14,"output_index":1,"item":{"id":"fc_0d54375cbcd869820168f239bf07c8819c860ab0101d690dd0","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence, Italy\"}","call_id":"call_xtoGn5KFzCOsLyeQv0INLRP3","name":"weather"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":15,"response":{"id":"resp_0d54375cbcd869820168f239bca94c819cb1dd488b92e67279","object":"response","created_at":1760704956,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[{"id":"rs_0d54375cbcd869820168f239bd1e6c819cb857543cb0e2660c","type":"reasoning","encrypted_content":"gAAAAABo8jm_AGutqoL73fW2d0o9tLvHVjgEVOuAmdXp5TeNZFZFEMSdvxcpOzSdtd6yO0lEEb4PTvUcM994h_d4knd6Gz4-Iko3UJMnvBf4k6gEgtbuW8bRIHkVz1m9psGGU6BLJ-w44uNoLkA_Hly6eu7LUYLP4Gq6FVwGIeMhtCRxsuOMAyKbZRc1_-Keo7E_pK7V48KWSfZN5JrxhG5ddgtFJsGXd0ELhcv9tkh_bNrXsJS8ao3OeOq_oA9c2SqtUCiLzqfkTNwyvS1k6W0nGBoHQbz_y0YO8QUIvZLkbTBBu-axHjl_aLwFfo52e97hS_XnvDwPp4u718QWOkVtfr7OZgDOGJLO5PXPrnh2mSwDPYI73s6X_j4fA776FF4tiDLKkie35mUF8fixgwgPmZ9yyHtIJIDaNVYSYx0fy4P0-c_p7kTjIP8IiTxZl3aKmUa72mTYAk4Qhiby5ys5l3WtuBz38wjNg-yZPlY5xszPZe2y8THCr4viOqsbSh7mytEvjx7Kbe3OumVayR4nBGf2t4q720vsYm3gb9WPyjhjB_5qBZUoK7C6kItlF_wuwExIogZKLtNB2fmqHGye5h8KdZmEnnduqetRXSOAystOZngHwOJOyL4nJr5QbdIaWp5sv8UNxQaJLjokRV_LCjSB007SbpMOTWiJgblKlpTBWVjAxnmbyRF0qXQvMO-XfXOrMwPXdjq23EVhTmNDRkC8JCtjV38oVdoqe07_nfXBXtby55oxqjeOs98AJF6Ch_lQkWK8KelZ8NzpVBeJqD5tcnGNeDD8qxvSk-SOYkiyAmYyXlMLUNRHU531hLyfCoo7Yn07oVmEIwmwLvV7qqLTH_W_pQI84lCp0M1dgoQewG7xiyd8RfGgySii0C3yBaKGcWrNJjQ_9876SgfY3ZMA5ArN9X612ixck_5L0Ff9OzAPwzpXzRI_j1SzG_so8h3yFm0-hs8RWSkGZU-kuMOubfkon7QjDP_NGyDFREDGLxK4n_NxbXx86TzuoRXAJNcdGeRG-5L1HRqkOgBHMKSSnPCv0gY3UvbAwy1kOYmqLSOubZ685WbbNOMyJTx-qXQ2cGdnE0oqEmL-WKVmOv8iDVWZ52iHgFfSOOzR88zeDVBjdb96uZBcysIMMwkFEvfmHLckN48HXKqEDRV6RbTsSgBp1bC8oseCWhxdBBNnSjXFJ7hBub_ACEMM-N227mQIhdURYfIt06IZOCgBscApwMkSOexzxDD-sXszF6GtXQToPjXDEv9oRvciRq-QOaTg2-KwjCaEDsf3KcpF0MPHkoZxmQKGd1MlyLo2ACjmb-N4KCqITw0h9V7GQFYEJK-zNa7ksveM4nfVFkU52ygZSv-yBz2onwjbY_g5jZRZWxLApb1R6gNAuf-gv_6b-6rNfqskQpdlwFZInqHvZWsZ-MFEw35Ea2dgQgKjlE6fWP6RKrGRO23gYAWf47jxOFTNbc3TrvXQCfXC_lqDm8v9gEIYIePJx3u4tf8RaPQ7CiJfTBWP57npDVE2QvHIugPtUMr3GtJSMwYVnAAwLbhKTugCPl48K4EV7tMb8KHER7jxQibyvPzLg8UE_lbrKQYm30-eN-FVUJIo-wx9xFT3eYMHfu25NJKf1QGFoqJQQ5bE2tlwP8bzMxnJt4StLxrWWxVh3pByhEfq68r0ge7gqa-SQO34vJK8UYs_8YMhjnAz0lJu6D6MVOuBRxrXG_-q65LQZz2JK64EOl7zuogJI2LitaZ15MB5qjyOOyjNLLIj-SsZrNkk9vMc_EGabOSDxVYlAVmuJY1x0ElswJS2nX2gHg==","summary":[]},{"id":"fc_0d54375cbcd869820168f239bf07c8819c860ab0101d690dd0","type":"function_call","status":"completed","arguments":"{\"location\":\"Florence, Italy\"}","call_id":"call_xtoGn5KFzCOsLyeQv0INLRP3","name":"weather"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":60,"input_tokens_details":{"cached_tokens":0},"output_tokens":150,"output_tokens_details":{"reasoning_tokens":128},"total_tokens":210},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 294.551333ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1764
+ host: ""
+ body: '{"store":false,"include":["reasoning.encrypted_content"],"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence, Italy?","type":"input_text"}],"role":"user"},{"id":"rs_0d54375cbcd869820168f239bd1e6c819cb857543cb0e2660c","summary":[],"encrypted_content":"gAAAAABo8jm966Ab9kxmDUu8vgpyqAPTcdexRXmAuzGq9I98ODGUbEphdXO5ikWTpzGh9YeGP_IkNo-9JsD1yJGbxWtqOGdDjTEs3QmNHUfa3UR-xqTzcjOvmq3thRE2DEQ5_-EXkPfYSAHkPn5lQXBECz6vkzRsncSK1EcTyGDrVXvnkRpiMdD3BWeA7wofiiZzcyk7j5R-BzDWH3TUE2ix3kqzCBY7dQJDHaLCqv-SSiIcmvqYNOxPmujSY_6O0PqJ6Ze5VzFs9pX3RLL2akYYKMjJF4gb6u7S_ZHKzjWWJcuywcn6t_b3l_PF3SL2MKPZLEGbHWIp8fCMo2FJbmHyJTI102X8rTLikr4qStE6oF0PzEHsbqrgXXE8BYDgGjF5dUbn_3Hm9yDJUWqZ4qoo8RuKLgBweNkaFOU_M3GC5vWHVSaAp5vNTwXZoWHm4sEa1Hp8tORuPFn-_Y-Tp6BuFViCZ86K9QIUcVRaTGYH_yFyqIKV7FhpQIbnp1p7GOEHUQksfk29ZlboKbylbOpTlt5sqgLY_MPUUiwJortZHikNr596BBhrGgylHBq57FK3hkIGYqBQ0XZQ9WT5jhNP3NmUDdjwNRfuh_nOGeRcXyP2otI9Cu_iWJF9lUBi4-1iwwEiTFrFc62WNGubgvYSd6nf4DcdDiO5VebGSrkdDKNt2lfV99wtHiVykHMtt6eNosHMdnmK1AVBNQhqEP94J-DnYEQeNgTzRsAUgjhiVG0UC5Gep5kYRA5oKlGZxIrmL9DD8kyCO7ASWltyv4y5sczvkQjS0LlulePcPPDofKaLZV8BzD7_alBKyeg1DrTxK0TRJWEP","type":"reasoning"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_xtoGn5KFzCOsLyeQv0INLRP3","name":"weather","type":"function_call"},{"call_id":"call_xtoGn5KFzCOsLyeQv0INLRP3","output":"40 C","type":"function_call_output"}],"model":"o4-mini","reasoning":{"effort":"high","summary":"auto"},"tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ event: response.created
+ data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0d54375cbcd869820168f239bf6a9c819c801b36862f6e7a61","object":"response","created_at":1760704959,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.in_progress
+ data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0d54375cbcd869820168f239bf6a9c819c801b36862f6e7a61","object":"response","created_at":1760704959,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"auto","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
+
+ event: response.output_item.added
+ data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","type":"message","status":"in_progress","content":[],"role":"assistant"}}
+
+ event: response.content_part.added
+ data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"cvpjFBvoJARCV"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" current","logprobs":[],"obfuscation":"r23DC7HG"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":6,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" temperature","logprobs":[],"obfuscation":"vw5U"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":7,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"g51yWh34TxVhZ"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":8,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" Florence","logprobs":[],"obfuscation":"B8h9Wg6"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":9,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":",","logprobs":[],"obfuscation":"LH9ks9NYw3Q65KG"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":10,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" Italy","logprobs":[],"obfuscation":"KZ7KqLPvqg"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":11,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" is","logprobs":[],"obfuscation":"hZ0HxwBJjNUPc"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":12,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"kHLsqD2S27DYjTo"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":"40","logprobs":[],"obfuscation":"qaVfQmMbDUPiGs"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":"°C","logprobs":[],"obfuscation":"KQr2dtLUTz416B"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":".","logprobs":[],"obfuscation":"5KwC7kdIdFYdnJ2"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" It","logprobs":[],"obfuscation":"XfIwteIiWTMyO"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":"ās","logprobs":[],"obfuscation":"8yRZZfbJxgatfU"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" quite","logprobs":[],"obfuscation":"ZF2PkVf3Pk"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" hot","logprobs":[],"obfuscation":"pkyDzfoOhyQk"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":"ā","logprobs":[],"obfuscation":"OqqqjEzO8fLvvSu"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":"make","logprobs":[],"obfuscation":"3jf5lV3C84Ck"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" sure","logprobs":[],"obfuscation":"6dFqxVXpm8e"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" to","logprobs":[],"obfuscation":"4OusNjUQ4vIrW"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" stay","logprobs":[],"obfuscation":"5EejczIY03X"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" hydrated","logprobs":[],"obfuscation":"Rd1Fv9i"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" and","logprobs":[],"obfuscation":"jMUvUMm7IENg"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" avoid","logprobs":[],"obfuscation":"fmsDpQ3bzl"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" being","logprobs":[],"obfuscation":"fbE6ah2tDh"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":29,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" out","logprobs":[],"obfuscation":"RkCDBQ4hjbJD"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":30,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"IZErEJhaQEKoc"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":31,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"hqvyeJZJz4rH"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":32,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" midday","logprobs":[],"obfuscation":"FJSIzJ4WT"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":33,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" sun","logprobs":[],"obfuscation":"G8x1ix01cpoz"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":34,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" if","logprobs":[],"obfuscation":"BwsVzUaVVuLUv"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":35,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":" possible","logprobs":[],"obfuscation":"fxhEfn5"}
+
+ event: response.output_text.delta
+ data: {"type":"response.output_text.delta","sequence_number":36,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"delta":"!","logprobs":[],"obfuscation":"HHcABqGoEgJfqI4"}
+
+ event: response.output_text.done
+ data: {"type":"response.output_text.done","sequence_number":37,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"text":"The current temperature in Florence, Italy is 40°C. Itās quite hotāmake sure to stay hydrated and avoid being out in the midday sun if possible!","logprobs":[]}
+
+ event: response.content_part.done
+ data: {"type":"response.content_part.done","sequence_number":38,"item_id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","output_index":0,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":"The current temperature in Florence, Italy is 40°C. Itās quite hotāmake sure to stay hydrated and avoid being out in the midday sun if possible!"}}
+
+ event: response.output_item.done
+ data: {"type":"response.output_item.done","sequence_number":39,"output_index":0,"item":{"id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current temperature in Florence, Italy is 40°C. Itās quite hotāmake sure to stay hydrated and avoid being out in the midday sun if possible!"}],"role":"assistant"}}
+
+ event: response.completed
+ data: {"type":"response.completed","sequence_number":40,"response":{"id":"resp_0d54375cbcd869820168f239bf6a9c819c801b36862f6e7a61","object":"response","created_at":1760704959,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"o4-mini-2025-04-16","output":[{"id":"msg_0d54375cbcd869820168f239c05098819c88648f5c1c886e75","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":"The current temperature in Florence, Italy is 40°C. Itās quite hotāmake sure to stay hydrated and avoid being out in the midday sun if possible!"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"high","summary":"detailed"},"safety_identifier":null,"service_tier":"default","store":false,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"function","description":"Get weather information for a location","name":"weather","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"strict":false}],"top_logprobs":0,"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":96,"input_tokens_details":{"cached_tokens":0},"output_tokens":37,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":133},"user":null,"metadata":{}}}
+
+ headers:
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ status: 200 OK
+ code: 200
+ duration: 545.923042ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenAIResponsesWithSummaryThinking/openai-o4-mini/thinking.yaml b/internal/fantasy/providertests/testdata/TestOpenAIResponsesWithSummaryThinking/openai-o4-mini/thinking.yaml
new file mode 100644
index 000000000..99c58f066
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenAIResponsesWithSummaryThinking/openai-o4-mini/thinking.yaml
@@ -0,0 +1,235 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 553
+ host: ""
+ body: '{"store":false,"include":["reasoning.encrypted_content"],"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence, Italy?","type":"input_text"}],"role":"user"}],"model":"o4-mini","reasoning":{"effort":"high","summary":"auto"},"tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_00f45739b037a2600168f239ace760819697f5959cb071a64f",
+ "object": "response",
+ "created_at": 1760704941,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": null,
+ "max_tool_calls": null,
+ "model": "o4-mini-2025-04-16",
+ "output": [
+ {
+ "id": "rs_00f45739b037a2600168f239ada3208196b9f9ec02572cc644",
+ "type": "reasoning",
+ "encrypted_content": "gAAAAABo8jm7xqIpOPbNnX4taz-HWeJL_L229xxdawa7BOkJxAeAguZU9nRYIQSTsFCLW2EzdVhj6SlCTbGTuOzEr_CvqREKlQ1IrSfW4e2-guPg_G3krEKwWcOrm3K8dIg_BWJe5Y-ogjUn30m0wU_IoaS7iJhtoiX5xbwBB4m9pymDyTF3otHTPLpkUeHI6zGJyETZYQ32bjQl8PKqortMp6JmUdRAEnVfGnbuG1SNOVkXvkk-j47eS0kkWnk4ioNvAWZaY6iWSETR80gx5eP3gBVeo80v3-PiuxoZIpIs31C8Y0ISSwC-cTlSvs_KFwzbnpkAiORU_mJ1DFQ6O2GatOy4sZvVwYxdUX3LIZs0tKbMJSbOoNVHDuq7PiiX8FZEno40og2M7YxE0uKhd291GhqY20vEvDA2f1lM2ILTHWm3r-TePkSy3XNcT60jieAhHoztL8u6GzOvkM_y96qVQebbsi8_dhzljZj2LETiV_VcnjKB4hjnA_9KULZLlD06sWJDCj2ePdeH383jcFZfp-ikum-8bC0JjW690R3GKFfCvY8RZb2UqTTj84mZuPsZ1rrB9onA3tXRbn77iYPds6pAKE2G4rc09FMh6RBFTRP5RRhkHpHO5uDpsR66UUKLhnv81ndbwuovwlDy4fqSSiJ7WTWdsu8zjUFWc5VgGFewQhMfV4pS5ue-y7YYqNVYzAx9sMw14FvWF6SZBnfcpgepOcCGnulaOOFFUe75H3voaQ5EJ38pE0zAXcgUtiSx_YdhVEPIAf7BGbDjZrE6dAns0d7PIhSqXYsV6c34DMwh0HmfQkQPx3BupQaMgfDMKsDovFLW3GsXe-YVk6d01UnMYEsIIMLByF5FpGCuc9bwGpgwljNf42HPaARLdWCGY6WW_ysxFebewRqSGMkMWVAZuR6khBJ89YnNThLWWR64nTwr_32OO2cTStvcn1YLP4jKhgz0YBu2EJuBJIYeHCP2xNEY-zL4_8Uld0bZDKaE3W54GK-eHwEJ1hEQqHhheCbFTYRzQWQEWYqjMG4pQlMboJrcJAfd4QF3tWwp4lCwLr6WGBUPwK9J0chjILV6Ry78Z829dPl2YI_lBmOtG1FsmtKBCj-tXTOfN0_lhhy57upsu9M2oH5Mb8iNj1M-LXlsQdsFqLjBkssagUQFjlMmXJiF2LbUdVvjFMAbMyWmEJLV5UzqsaLClYA6sSun8dDpml4Z0FfxLysfmXUdo1NGYhrN166U_kC8779mREHTkGBvtHwsW_5CTQLIRbZtixV0yK0giOuUuVcxfnK6x0_Gcvu_frnUWji_FD71sa02y_1-3wrzyCckhzNhvb4nZEliu2DcuYk9LGrhbNZZRhBDKFwP2CMm4L3HLaPbThc7WCIaYa_pmoLGRQaWHjUoyU8yakbR3z8km1YEMHoxLIp2furli6y7S9KYSfO3ewh8AHrDf7JKesHEAynvYZp6qS3wehOIFwfewwZJhI09HOgpgRPTLc9PQcuEDSGj0BRzCAX6Iom06x-adsHrnJS9LtH1WcR8OOF4D02R9pjnXwvoSsWiUoSKbM3-b4HPdnupqq7FAQsvwlUy7n8yE8Mz0nIlejbOTCsg1nfJ2enzLD2JcdtPdG1bQI-GNGmBabPWt_YHolQ6pMlfhx8QZSn0gLgrL0nJeB5nZiP06xsEflkcVUXfiu8spA1tkxu8VYH_HuamCJlnr-BYXsiOuUmCYq5LJLB2dcVYoH_7HrQHE0m4vgl3abTNwBIsHyb-tomHiVQZoET9MfTYaNckcGQ-WAYjd5Eu37Tu13dfde_Nx7Wz0pRRPDonmBGRFuotdaL7Ey6WnzcDinRbqNke6tF1pIN9fjN5U5yYa0uvpbKVAVAO7kBdO7-Ns6MsqI21CdS0A6SS9C4n6sjCdiJ4vDzDJWXpH4PAytK6dLcW1KoRV9GXjYl5wfd2xcQeO0AVx9xfDHuQwk7i_CvDaaqqFq4tKCzKvOdc7bULf7xKyHxzrGbXoiH1EEWfrzIP8P7xZdPHNDPj9LS5iKDHM9SJX6Nfefnmjr6PX3C7imyiKebGT7Ap0sNjXsvpMRBtHNaVji29qjFXhXKBQSRnIjfng1bFboSpgqLUEzT8Z_K87cGkb4M8QcJgeiBOfAs0GSV5fE6OY-u1vOfuivmqjzxjWpstxrsUSnPPQtNk9NfJERLzhvUZmeZBExiN7O32_2iwExbFwxMCPn3XShR92CIHB7-rIeZV-gVPLcKJUy4EueclfHDFDZbbp5Pj37hZr3Q2dqarGyDcnMXIss_bsFHH73wOKiusvX5GR1LDFqKnTkDXwhkCUMIPwET9h6N9VaS_cAjFUwIfXc4KsbNCws2s3N8ZIGaQR1R1gIGxG7O0lfEA7kwDff76CT11G9I7De5GLCev5sJiZtT5qxjKUckKlM8WkfvwjhDHnhwV_rmiodeU5YnodTMHdzzd7FNBopEr9sOv2p9iiaxrVq0xcjw7sY3zd6yFnDPg4P5KEz2SieNYZi-KefO10KtjnaiqNnxxWmL8_wJhyRru_bwiU4X35Ajob7uYrV3yuo_IK_AJ49KuXsS8ISiSmFPiOyQPIhTPqbm1fN6o8WfAhVVuIcZ5xIOIzTaXLyHp7m3JkzXEbwTIZvJSKXXGyhj0XRZSCraQVj1MRYdhHBARORP0VrgQ7Nrg5ymIM7v0NFDSkSWDAVtIbvZIbQFzHkfiUh8W3CBe2XJNpsvyUAEi_yxCfEWOBdVuqqXQPwWFDI1dbPSmqq266JS4bJ9yBONfme0RZK1fFKCGtRFQQygHlF7NJMirCvYqKV4aZRA-mF36HlGRdSkDioZAyVHpMpZ4QVr2bUW0sx7wJMi3VhtLlCEzP5o2syZHPl5VaU70iyNkt9L5I3dIZVQ1z8ejV7Fh8oDjBoPcEhf8510ykm-wXgiqz9Kanb_fgQZX_PS66EY7EFTbGVmoDNlbwTg6XzjNYa8qPIP-rLL-sGkXubNT8l2xRZcehu7QQ4bG5X3sy6QA9lpGGD5sPk3aa3_F84FEclxIlmQOUy1Ng5bWgnzPRDWU4Bx4M6k6empXQZvOawobsA9EZOVoem0yB9WfcoVLVzFaGqUpZ00477PeLb37ARxN94hCo6z7Z39hbd3tHWji7Dv632im-S36nJIGLhFkR1idC0BtdDBRtG-RcCzBv2iPFflnmXe7f_j8TLyBcOZ0NoIcwpycD3ry6FWrYNlQuioNDZeqmBspShklQvfmeX7BVU9vJA3N1tdhjR4Go7uitaccWBSIEYPbnPe4rYBlFQ3iUaWKAf-_aszAArg8uOyKACBGltCzWWJjQsoivdMplSUtV9n7ZpcNcY3JZcSdWlkuDa6xFx1RnMKTuwbZZ7SuMcv9XX5Kp1tXbIdo1PYnECKHvkqICn5xSJyB9FP3XXoBmr1dpNucd4F288y0KuwTuDigViZnec_X4g81_tClm5634xyyH5-4Ew46hqre_UQULwnOtYjFIfnSmSwzmgLNGibE_h577aRO57miyAr05j-asTnpoOnDMIcw6yzQRdgToiiCmf4ZKRjKsKYCzYBLdobjxewLdF4BdeYIlbwyVy56nyn0fxo9ALvW_JRnEnWmkA_lvzn7qAlCm3Z1gWma2HGoCmnCGxTRSYc1LxLrSkR1-T17PiL-0uLVU_z7eve2d8FJ9x6HU4euqpeV7bcf2TIWsYXhiDbBO3UnU8OhkVlKpEMsQEX2-aljJvsz0StYaDpgU1ivBVW389ZR5No5YiE6_SVYxjAzL7JuONFbxrxZiurlZRsL966JEGUdjXQHgVd2R3NU7bfkNPHinLwb-31IYCxHccmW8xxHd8Gw0cSlZq2iMPQ4LVm7vLhexwuvqWfoV5agGmU8Oebxjbffm1f4QCIsc-AcdkEZ0OO1mAZUpvFI5XVUUF9xtCmFA06ML3VcGZi-j7I4bxJ6A70-S0Gko5vJW7s7obQGVrBqY9TINilJrUKhSGu5vqiQ_8uyfCk96pqFGSVi-jT1bKlUBbyrXcjqjMOgeiw3jluzDND-GM31wK7V-DzICcBNaGq9dws1HZXThm6-nwnEe6VxTTNidlr2NKkiGXufdGDSqb2MrwXca_-j0d1Y048QswFa5DJ6HRF-Y7vI6Td_3hjlXGhfo0XWKY00J6jFdnjEVAzcYF7rcruXQzHfT8FPp7SWgQeu6arM3VrIp4y1aFim_zypRRXs6HxRzPwf7gH9aaZ1-l2UpVOGRKtUUKIreWNlkZCFTifYEoxYrSAuxI53exaHN-y1fVthU5XD7oEf2rLrb1zRF8aqFf-v9bq_5ymWTDTkUjheS_qql-SWtvg1-yvNHjQSiljS4BN2GUUnmX69BxsuC31aTi0off6fgOB8oh3M9FvhkwlaP16oLvghsLMT8fiB8xC8voPXhxAAz8tsTWRDLihKqR7F4l7bmRBbi5dqIftL_UyzTiScRITUl1NMElID5Nu6nJI78rwpTDyj9cD9E7C8nxkqZ4xSlClwWkAfnl19h3jAvcoVamuayGXEdzUYQiQ9ZndH4Loi1MIPkcdek7VOJKbPFet9IwW1hYdH3KClVCbwzTgkIpwPVuAQnqY1wbe--wepgI-4n5EOn7UwN86EpMZ04V7tUw5VwTpEWKDvXaUdjcy8n91M5AOFAXP5PnhZwPGPUCzF69a7cvhSxlm3wwqqeUWEvQECfO37QjQ0kCgnXH6u66JooCvfw7gXau5ipfQ2sVXwCetc96R7QYA3eDNod7kWOYQFqJf98wnrXxM1mvuSo7pNcWoYH2yBOt-QEt6fPr_eGl0bzreAcW92SBwS4KNkFQCYyfM_5f2kvZO0-VoOYCIZJK_jfByWYLPaDGmm0q1QuziP4GvCaM2wIz8jnRSJCZct4scxZLv4zyzqwyALgXccUFMlpiSb_W6YNft7L0vUNNVCIW_o64dj7vrmmsu96qnK83TOK3QsPq48S1-C4bTB3eGgjFCs8aKh47u4W2EfJLNv5o_zEymCutj5cHRpIM-vvVfiVPAfaLp4uvHhPDGs_Ef2z980447hoqzIjlf5Dt8f-1P_oRFbhIJjH8QlkRXfHKYcpqw_Pj16bbPNRpybiVDndKVUH5-Bl9xRUeYlv5cWnoL9eqZaQMJuj8yzXLW-EHQtJzZxkc5ZpKAzxWHa6C2-yeC0ysjurv8dS8Toz2ADzaS0_q_jJTTUBTQLnzY2iKXgL8ieyxM6GeRrR3e9JzoIvR8mb-v6i8Mho4d1y8iGuEcPBuB9BXXdKNvI_QZY2s4j8Tot3WZszT7IeiD8xlRL59bSYMlZDubIEhrZa88g2UETPqWK8hQlPt4Faa1YfuU1O7PZr0pa82BJWZHxeDGDbLxbSzDg39cngXcKpaE-1TOm-dgzVvPc0oxxOhw9AkFQOqHuWbIQhLOH9rIsu6RPhaDspnW_o3XlzzkjPsqGg8wmMOwZQ9EAFKV7imlj93FjfqxHdTX061lBSl9euneWTSrTBQjqNx3jkUdfa5sOh8YGt-eycbISmPfvH5N0cAow3Y7MD2aEeG6xlHznVZPrZ4xBKjixX514THnQiaZwUFNjWPjXwT9rGBDHyMbEbNSrZF2bgd3KYexNTirLNX-wvJld6kb87Kk-WpDaaGxtyCOj02aoleC5Ph-GhkqVMsxncrcMZeN6liUxRfNWtuVbfkWj9Bp-xT0qi0Fb9vN-2T98GbS66zNpFa96lrf9IVMgWR6h3u8-TXL4WzdAg_YQpmWZpqVfj_1oWpCgS0DU1bSLz0iFRMYw4FRoKMLRx8mjfmoQnqzStrTNiyk9JjYte5_Uy9NeQaCcoEYBAs1n3JZb-HsnHxM3En4dL28snqfHAqfUBxX6u63uSsnF3lJhtry5vFpeIEN4lrrH10QIbLmjf-5fPHTq1QY31XaaZ3VkAtlOxgL2-jkQMynlcfXw8YrovBtetSozLXW_M0BS7N2kZOfLSd03Dd0BIoPOJ40VmlnXYmNanjb1wv_DJFaaT95Pp_idVoTFAztHW9F7XEMLpfXjH51j1Fe7MhZcgCy4Ef_gGrHFFc_gL0JD_xtnEjBnK8IZhufUrmJIgeDgsmQ3BcvW4qKJd7ot9BLwof7DP4stxD6_8lh62kosEoHog4HeUStwqa8S5NlOrlW5kSv9seQRr87hMIyX0NUJRkc6REAtgAygV9tceCVCh7P5KNaNWmuK-AoLLsQJLK59kiV-UdjUxXWWloKZh541qf-ua_kc0ne1Y8W6yet4Mw7bbgQGMQcuUUOz17E5EQBJrm4ZVV3iRv9N71h8qZi7aiCzsIWEE350K9T9F2py91ObA-Xi4SXQK4WEd05O1lLi4ag4XNvZ0x34p2nPoaxpoCNvCVp1icxwjlCagZ-qjjKwmNt83SRRAe7uwyDVwB8G2tkh9Paqt4TFTcjOJhEwVrLm1SlLV8oBLVKsmtnT9fW2DKlZNdfMVOwYzkufwc7W25i5yVj2fYdgJlQvSkwZx5a5JN8kuO0NIQwJ6NFla_qW7io0_BwE_zvgMgZ2HNUc4lGY1K0sEmAsm8Yv7b4qxhx0o829wdsBcBSWVhUMdSuksOisr4WiSurexcKkhJVufl7NspCVFHeNeYr2c07dS06bk_xafqIxkuyn0mQt5fYjFbLN-oZiN2txDLzx3KIuYOe1Z9_EsjEbWPp7uNNRfEpynlf0EGJ_ZFW1_zkgyuBNoWwcwZnyQOAN12EbGwnw1RzGfPouzgxKAKAcJEuJHhbyghWOC4Yk2lK56QuiZss4CFlTThhFCTFJ1fF3N6VWoPwUUzY5UWfsIlqIgOCUHNDKCI18pDuYd2rCixKHs7PLOoVdUOU1lv-6iKuGfPrhG9Xo56KX9PDOfVwO1TRa-hICs8oF7vnlFiCDnMO2Kgt_NKLDpvE3apafxx8a4PIFNc1EUjA6kZzCVjILgksTrZOUDqZP2AdpEMPU4Vg2v-IxZSqEY0arQsAtMkdESS437QvDoa-UJhMv0Rid27HUAKgkKA7yVZCsC_n1xiOm-cqGD_jei_iAakDPnBQdX678UG9kJmcuyj__C8tPmRnRVZwt1peaMqo-Z2xISMH3BzxI1S2HrLgiSp4epUo3nAFfN1M0ugQdK8mTKSzBjxCeL13-bQa7vaAqtFjrMQrwTlRJpL1tUQKjC_nrjgYY4sObO8FokbFx9rH_aPH9I0IXrd2lFktTMRtp0ETSmzc7FKyzMLZRxAP6x84Mv3hXmT82e96LbE4maeFJTkaILrV8e03x-CetgcsIzCN9PvQdTQqcUw9Ml-GxL1896zBje5lwEZEtDXVyfpwr-cE8NGiRp59dE2Fs47ogMgZsHJqpYJlimj2lP2ExgHYgogsNOj9yM7YxlbVJpLlo5RtynA6GWzLnV9BSSjrkXBM444SZILrx2-rBSDeAlQH4ViYa16EHunLPXyWBzCxth2ubmoAkqxsPTr-fa6JjoZlWecg0QH6H6PTXVd01QwS68Bbwrcj8n35LLNaWVm5Dpy46lMzPaYFJlW4dpXVRJ2WVkLnTyPdsnWIqQ22K4xeZP1mTxZPf-XYVC6eHD5PBQmx8cUiqYLe0WA9pvtKwkfLjAuGlZbm-N6SMgs1Wcik2dlFL15TDJJv58DHxZcEGk5RNz4daVQNQLMyav5AhcwF8wC20AcjS0pjsEKGXPXKur7CtyfkPHA0MBlDEZre6nenkXo6jp-ZTgqxYJCXZXgZqLX9Qw9tibmt1Sf9x85XaAkq7hXikPZdHyWczjdS4YA-3gSnwpJ5gS-0tetWag6fkzkI4qHFMg9UrNXGVxrxsEUH9Jbwj49VJAJkgSJWVJgOSPtKPPwzAiSMWWttiFTVCVLXB3tbn-kHMUlvlf_zlTyS2HXHFyIZpqTpwyco6LyST7PBvJan_c99eAGmkOW5Yzua_EeVwSOlHs9s-1cDxkxGPVyz3GXRm_T1qKZ68ILQtUc8c8hNbvgbn7ctnkSIMHSzHoBw0rHaMRX1KDB3j-s-3Uys9myyChiqufM4L9V5aaXlnN91mv4vPURzIVS5TReWqjN7z7lm4M8WgcjkDj9Rvx60qD73CDkJLy77uFT6iJXKDneM1YSKse4r20zQ0OkwcDjb7iEowcqHgvx5KEppKdBWccZWVNHJXZl-tfGI5lWbDPwuWuEK64RIXZJe6JykSphNbWzz5oSp4aMqv4MFWggcKdYkVrlGovI3EpLElDHqBswUUxNJ2JWyJfdtWujOWmNrhpKZbq6EvqrqFd94X2Ay5D_Xz3EO4jRJZhbw4uRUAlrFDRoBUtZ0gFeL-N6ab6_sVdR3U6BV1hchCT-v7Zbt5No_4ULgQ4xb4QYqHL3DVwqfm8UPlGhivAc5n8QFjv-e86xERdWI39x7fE6v2oWCzLmQKW5GBX7ohbbQyOU3c96Haa-N2EQOjms5pQfa4-YJ5E_o4n6LSLtprIfY-3O316UfQNTvbsSkYv447LwoyS-9sHBklvC8RbN36s71UOrCLbGk9S6ypfxnIRYPmrhpd1wHT_jB0fCqQJZwgI5mILYqXnH-uqoHKjUqSPgHnhzT-iVqVSBE6Zq8xqUut-LqESULZ81A35SiGwlYrIQy5dHs5wadUIdbNz1ZWWI2ZybVTE39Ukv1DQp9MrhmYJZYrapTpguEN2me-EBjNNnpLRDsO86eSQAhVzV9J000jIvXxGdlUo3SKwZfM-1P0L2CdhicIgI7-KVSGrpJPxQA00Keey2Oj4P6Vdzsrp362WNlkuMIqueVSfRl8P63JzASuXCRlPwDKZ19D15h36uiyvgtBsKhPeAbzGfM7UTLFU-q5vP1gHgpiLqs6Bw61oo7E51yTu6zrmHukuao-AOGhKbctckfrvrVuZ7PpxD_tuQCoYeHUCW8-cjsh8rVsaA0TOo8g_TGpM-c47gXMYjUbfoo-mJV2hBZSW4a3npoZMgCCgPchFzJONFqs7VEcaVS6a6oXDl3woqq0v_LzNLfoGll6ixi9c5okjLeTvf3z6MROAabvxedMD8u8dkLqvL86q7d4FDrvBZDM8E5DbryvvVRPp9rfSa7KLwInjrM9bzpnV4e7TTk7-LDKg54YU8GF_RLC2vIdOvCRGE23BfG2KZVZof3rmhMITLEbGCSL9zd34d2YXhdqbOsTJ2DaZq_Nwii1lx5RBSf_6RSKyPwm0Q7vP30QKAE6FBMHqr2CQwsldDC9R-nI9Y_FNIrbo03lkz7TQe66pBOCUL22IXO1tcdw6PHnowVfOoI_pzrEAwP66gwnTC7Ysb7hREsTH9SIO-EZvPAb_045jovUfYTQmdYZmTgyr-zPzWn-jkprYnHEUX82Hn7LN3cTjRRNvhH9ELSmfrWYhRaW2Q==",
+ "summary": []
+ },
+ {
+ "id": "fc_00f45739b037a2600168f239bb58b88196b17b26934fd24de2",
+ "type": "function_call",
+ "status": "completed",
+ "arguments": "{\"location\":\"Florence, Italy\"}",
+ "call_id": "call_ewLJJaD4OO6pdsTnaDtMuNn0",
+ "name": "weather"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "high",
+ "summary": "detailed"
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 60,
+ "input_tokens_details": {
+ "cached_tokens": 0
+ },
+ "output_tokens": 1302,
+ "output_tokens_details": {
+ "reasoning_tokens": 1280
+ },
+ "total_tokens": 1362
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 14.800628916s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 10319
+ host: ""
+ body: '{"store":false,"include":["reasoning.encrypted_content"],"input":[{"content":"You are a helpful assistant","role":"developer"},{"content":[{"text":"What''s the weather in Florence, Italy?","type":"input_text"}],"role":"user"},{"id":"rs_00f45739b037a2600168f239ada3208196b9f9ec02572cc644","summary":[{"text":"","type":"summary_text"}],"encrypted_content":"gAAAAABo8jm7xqIpOPbNnX4taz-HWeJL_L229xxdawa7BOkJxAeAguZU9nRYIQSTsFCLW2EzdVhj6SlCTbGTuOzEr_CvqREKlQ1IrSfW4e2-guPg_G3krEKwWcOrm3K8dIg_BWJe5Y-ogjUn30m0wU_IoaS7iJhtoiX5xbwBB4m9pymDyTF3otHTPLpkUeHI6zGJyETZYQ32bjQl8PKqortMp6JmUdRAEnVfGnbuG1SNOVkXvkk-j47eS0kkWnk4ioNvAWZaY6iWSETR80gx5eP3gBVeo80v3-PiuxoZIpIs31C8Y0ISSwC-cTlSvs_KFwzbnpkAiORU_mJ1DFQ6O2GatOy4sZvVwYxdUX3LIZs0tKbMJSbOoNVHDuq7PiiX8FZEno40og2M7YxE0uKhd291GhqY20vEvDA2f1lM2ILTHWm3r-TePkSy3XNcT60jieAhHoztL8u6GzOvkM_y96qVQebbsi8_dhzljZj2LETiV_VcnjKB4hjnA_9KULZLlD06sWJDCj2ePdeH383jcFZfp-ikum-8bC0JjW690R3GKFfCvY8RZb2UqTTj84mZuPsZ1rrB9onA3tXRbn77iYPds6pAKE2G4rc09FMh6RBFTRP5RRhkHpHO5uDpsR66UUKLhnv81ndbwuovwlDy4fqSSiJ7WTWdsu8zjUFWc5VgGFewQhMfV4pS5ue-y7YYqNVYzAx9sMw14FvWF6SZBnfcpgepOcCGnulaOOFFUe75H3voaQ5EJ38pE0zAXcgUtiSx_YdhVEPIAf7BGbDjZrE6dAns0d7PIhSqXYsV6c34DMwh0HmfQkQPx3BupQaMgfDMKsDovFLW3GsXe-YVk6d01UnMYEsIIMLByF5FpGCuc9bwGpgwljNf42HPaARLdWCGY6WW_ysxFebewRqSGMkMWVAZuR6khBJ89YnNThLWWR64nTwr_32OO2cTStvcn1YLP4jKhgz0YBu2EJuBJIYeHCP2xNEY-zL4_8Uld0bZDKaE3W54GK-eHwEJ1hEQqHhheCbFTYRzQWQEWYqjMG4pQlMboJrcJAfd4QF3tWwp4lCwLr6WGBUPwK9J0chjILV6Ry78Z829dPl2YI_lBmOtG1FsmtKBCj-tXTOfN0_lhhy57upsu9M2oH5Mb8iNj1M-LXlsQdsFqLjBkssagUQFjlMmXJiF2LbUdVvjFMAbMyWmEJLV5UzqsaLClYA6sSun8dDpml4Z0FfxLysfmXUdo1NGYhrN166U_kC8779mREHTkGBvtHwsW_5CTQLIRbZtixV0yK0giOuUuVcxfnK6x0_Gcvu_frnUWji_FD71sa02y_1-3wrzyCckhzNhvb4nZEliu2DcuYk9LGrhbNZZRhBDKFwP2CMm4L3HLaPbThc7WCIaYa_pmoLGRQaWHjUoyU8yakbR3z8km1YEMHoxLIp2furli6y7S9KYSfO3ewh8AHrDf7JKesHEAynvYZp6qS3wehOIFwfewwZJhI09HOgpgRPTLc9PQcuEDSGj0BRzCAX6Iom06x-adsHrnJS9LtH1WcR8OOF4D02R9pjnXwvoSsWiUoSKbM3-b4HPdnupqq7FAQsvwlUy7n8yE8Mz0nIlejbOTCsg1nfJ2enzLD2JcdtPdG1bQI-GNGmBabPWt_YHolQ6pMlfhx8QZSn0gLgrL0nJeB5nZiP06xsEflkcVUXfiu8spA1tkxu8VYH_HuamCJlnr-BYXsiOuUmCYq5LJLB2dcVYoH_7HrQHE0m4vgl3abTNwBIsHyb-tomHiVQZoET9MfTYaNckcGQ-WAYjd5Eu37Tu13dfde_Nx7Wz0pRRPDonmBGRFuotdaL7Ey6WnzcDinRbqNke6tF1pIN9fjN5U5yYa0uvpbKVAVAO7kBdO7-Ns6MsqI21CdS0A6SS9C4n6sjCdiJ4vDzDJWXpH4PAytK6dLcW1KoRV9GXjYl5wfd2xcQeO0AVx9xfDHuQwk7i_CvDaaqqFq4tKCzKvOdc7bULf7xKyHxzrGbXoiH1EEWfrzIP8P7xZdPHNDPj9LS5iKDHM9SJX6Nfefnmjr6PX3C7imyiKebGT7Ap0sNjXsvpMRBtHNaVji29qjFXhXKBQSRnIjfng1bFboSpgqLUEzT8Z_K87cGkb4M8QcJgeiBOfAs0GSV5fE6OY-u1vOfuivmqjzxjWpstxrsUSnPPQtNk9NfJERLzhvUZmeZBExiN7O32_2iwExbFwxMCPn3XShR92CIHB7-rIeZV-gVPLcKJUy4EueclfHDFDZbbp5Pj37hZr3Q2dqarGyDcnMXIss_bsFHH73wOKiusvX5GR1LDFqKnTkDXwhkCUMIPwET9h6N9VaS_cAjFUwIfXc4KsbNCws2s3N8ZIGaQR1R1gIGxG7O0lfEA7kwDff76CT11G9I7De5GLCev5sJiZtT5qxjKUckKlM8WkfvwjhDHnhwV_rmiodeU5YnodTMHdzzd7FNBopEr9sOv2p9iiaxrVq0xcjw7sY3zd6yFnDPg4P5KEz2SieNYZi-KefO10KtjnaiqNnxxWmL8_wJhyRru_bwiU4X35Ajob7uYrV3yuo_IK_AJ49KuXsS8ISiSmFPiOyQPIhTPqbm1fN6o8WfAhVVuIcZ5xIOIzTaXLyHp7m3JkzXEbwTIZvJSKXXGyhj0XRZSCraQVj1MRYdhHBARORP0VrgQ7Nrg5ymIM7v0NFDSkSWDAVtIbvZIbQFzHkfiUh8W3CBe2XJNpsvyUAEi_yxCfEWOBdVuqqXQPwWFDI1dbPSmqq266JS4bJ9yBONfme0RZK1fFKCGtRFQQygHlF7NJMirCvYqKV4aZRA-mF36HlGRdSkDioZAyVHpMpZ4QVr2bUW0sx7wJMi3VhtLlCEzP5o2syZHPl5VaU70iyNkt9L5I3dIZVQ1z8ejV7Fh8oDjBoPcEhf8510ykm-wXgiqz9Kanb_fgQZX_PS66EY7EFTbGVmoDNlbwTg6XzjNYa8qPIP-rLL-sGkXubNT8l2xRZcehu7QQ4bG5X3sy6QA9lpGGD5sPk3aa3_F84FEclxIlmQOUy1Ng5bWgnzPRDWU4Bx4M6k6empXQZvOawobsA9EZOVoem0yB9WfcoVLVzFaGqUpZ00477PeLb37ARxN94hCo6z7Z39hbd3tHWji7Dv632im-S36nJIGLhFkR1idC0BtdDBRtG-RcCzBv2iPFflnmXe7f_j8TLyBcOZ0NoIcwpycD3ry6FWrYNlQuioNDZeqmBspShklQvfmeX7BVU9vJA3N1tdhjR4Go7uitaccWBSIEYPbnPe4rYBlFQ3iUaWKAf-_aszAArg8uOyKACBGltCzWWJjQsoivdMplSUtV9n7ZpcNcY3JZcSdWlkuDa6xFx1RnMKTuwbZZ7SuMcv9XX5Kp1tXbIdo1PYnECKHvkqICn5xSJyB9FP3XXoBmr1dpNucd4F288y0KuwTuDigViZnec_X4g81_tClm5634xyyH5-4Ew46hqre_UQULwnOtYjFIfnSmSwzmgLNGibE_h577aRO57miyAr05j-asTnpoOnDMIcw6yzQRdgToiiCmf4ZKRjKsKYCzYBLdobjxewLdF4BdeYIlbwyVy56nyn0fxo9ALvW_JRnEnWmkA_lvzn7qAlCm3Z1gWma2HGoCmnCGxTRSYc1LxLrSkR1-T17PiL-0uLVU_z7eve2d8FJ9x6HU4euqpeV7bcf2TIWsYXhiDbBO3UnU8OhkVlKpEMsQEX2-aljJvsz0StYaDpgU1ivBVW389ZR5No5YiE6_SVYxjAzL7JuONFbxrxZiurlZRsL966JEGUdjXQHgVd2R3NU7bfkNPHinLwb-31IYCxHccmW8xxHd8Gw0cSlZq2iMPQ4LVm7vLhexwuvqWfoV5agGmU8Oebxjbffm1f4QCIsc-AcdkEZ0OO1mAZUpvFI5XVUUF9xtCmFA06ML3VcGZi-j7I4bxJ6A70-S0Gko5vJW7s7obQGVrBqY9TINilJrUKhSGu5vqiQ_8uyfCk96pqFGSVi-jT1bKlUBbyrXcjqjMOgeiw3jluzDND-GM31wK7V-DzICcBNaGq9dws1HZXThm6-nwnEe6VxTTNidlr2NKkiGXufdGDSqb2MrwXca_-j0d1Y048QswFa5DJ6HRF-Y7vI6Td_3hjlXGhfo0XWKY00J6jFdnjEVAzcYF7rcruXQzHfT8FPp7SWgQeu6arM3VrIp4y1aFim_zypRRXs6HxRzPwf7gH9aaZ1-l2UpVOGRKtUUKIreWNlkZCFTifYEoxYrSAuxI53exaHN-y1fVthU5XD7oEf2rLrb1zRF8aqFf-v9bq_5ymWTDTkUjheS_qql-SWtvg1-yvNHjQSiljS4BN2GUUnmX69BxsuC31aTi0off6fgOB8oh3M9FvhkwlaP16oLvghsLMT8fiB8xC8voPXhxAAz8tsTWRDLihKqR7F4l7bmRBbi5dqIftL_UyzTiScRITUl1NMElID5Nu6nJI78rwpTDyj9cD9E7C8nxkqZ4xSlClwWkAfnl19h3jAvcoVamuayGXEdzUYQiQ9ZndH4Loi1MIPkcdek7VOJKbPFet9IwW1hYdH3KClVCbwzTgkIpwPVuAQnqY1wbe--wepgI-4n5EOn7UwN86EpMZ04V7tUw5VwTpEWKDvXaUdjcy8n91M5AOFAXP5PnhZwPGPUCzF69a7cvhSxlm3wwqqeUWEvQECfO37QjQ0kCgnXH6u66JooCvfw7gXau5ipfQ2sVXwCetc96R7QYA3eDNod7kWOYQFqJf98wnrXxM1mvuSo7pNcWoYH2yBOt-QEt6fPr_eGl0bzreAcW92SBwS4KNkFQCYyfM_5f2kvZO0-VoOYCIZJK_jfByWYLPaDGmm0q1QuziP4GvCaM2wIz8jnRSJCZct4scxZLv4zyzqwyALgXccUFMlpiSb_W6YNft7L0vUNNVCIW_o64dj7vrmmsu96qnK83TOK3QsPq48S1-C4bTB3eGgjFCs8aKh47u4W2EfJLNv5o_zEymCutj5cHRpIM-vvVfiVPAfaLp4uvHhPDGs_Ef2z980447hoqzIjlf5Dt8f-1P_oRFbhIJjH8QlkRXfHKYcpqw_Pj16bbPNRpybiVDndKVUH5-Bl9xRUeYlv5cWnoL9eqZaQMJuj8yzXLW-EHQtJzZxkc5ZpKAzxWHa6C2-yeC0ysjurv8dS8Toz2ADzaS0_q_jJTTUBTQLnzY2iKXgL8ieyxM6GeRrR3e9JzoIvR8mb-v6i8Mho4d1y8iGuEcPBuB9BXXdKNvI_QZY2s4j8Tot3WZszT7IeiD8xlRL59bSYMlZDubIEhrZa88g2UETPqWK8hQlPt4Faa1YfuU1O7PZr0pa82BJWZHxeDGDbLxbSzDg39cngXcKpaE-1TOm-dgzVvPc0oxxOhw9AkFQOqHuWbIQhLOH9rIsu6RPhaDspnW_o3XlzzkjPsqGg8wmMOwZQ9EAFKV7imlj93FjfqxHdTX061lBSl9euneWTSrTBQjqNx3jkUdfa5sOh8YGt-eycbISmPfvH5N0cAow3Y7MD2aEeG6xlHznVZPrZ4xBKjixX514THnQiaZwUFNjWPjXwT9rGBDHyMbEbNSrZF2bgd3KYexNTirLNX-wvJld6kb87Kk-WpDaaGxtyCOj02aoleC5Ph-GhkqVMsxncrcMZeN6liUxRfNWtuVbfkWj9Bp-xT0qi0Fb9vN-2T98GbS66zNpFa96lrf9IVMgWR6h3u8-TXL4WzdAg_YQpmWZpqVfj_1oWpCgS0DU1bSLz0iFRMYw4FRoKMLRx8mjfmoQnqzStrTNiyk9JjYte5_Uy9NeQaCcoEYBAs1n3JZb-HsnHxM3En4dL28snqfHAqfUBxX6u63uSsnF3lJhtry5vFpeIEN4lrrH10QIbLmjf-5fPHTq1QY31XaaZ3VkAtlOxgL2-jkQMynlcfXw8YrovBtetSozLXW_M0BS7N2kZOfLSd03Dd0BIoPOJ40VmlnXYmNanjb1wv_DJFaaT95Pp_idVoTFAztHW9F7XEMLpfXjH51j1Fe7MhZcgCy4Ef_gGrHFFc_gL0JD_xtnEjBnK8IZhufUrmJIgeDgsmQ3BcvW4qKJd7ot9BLwof7DP4stxD6_8lh62kosEoHog4HeUStwqa8S5NlOrlW5kSv9seQRr87hMIyX0NUJRkc6REAtgAygV9tceCVCh7P5KNaNWmuK-AoLLsQJLK59kiV-UdjUxXWWloKZh541qf-ua_kc0ne1Y8W6yet4Mw7bbgQGMQcuUUOz17E5EQBJrm4ZVV3iRv9N71h8qZi7aiCzsIWEE350K9T9F2py91ObA-Xi4SXQK4WEd05O1lLi4ag4XNvZ0x34p2nPoaxpoCNvCVp1icxwjlCagZ-qjjKwmNt83SRRAe7uwyDVwB8G2tkh9Paqt4TFTcjOJhEwVrLm1SlLV8oBLVKsmtnT9fW2DKlZNdfMVOwYzkufwc7W25i5yVj2fYdgJlQvSkwZx5a5JN8kuO0NIQwJ6NFla_qW7io0_BwE_zvgMgZ2HNUc4lGY1K0sEmAsm8Yv7b4qxhx0o829wdsBcBSWVhUMdSuksOisr4WiSurexcKkhJVufl7NspCVFHeNeYr2c07dS06bk_xafqIxkuyn0mQt5fYjFbLN-oZiN2txDLzx3KIuYOe1Z9_EsjEbWPp7uNNRfEpynlf0EGJ_ZFW1_zkgyuBNoWwcwZnyQOAN12EbGwnw1RzGfPouzgxKAKAcJEuJHhbyghWOC4Yk2lK56QuiZss4CFlTThhFCTFJ1fF3N6VWoPwUUzY5UWfsIlqIgOCUHNDKCI18pDuYd2rCixKHs7PLOoVdUOU1lv-6iKuGfPrhG9Xo56KX9PDOfVwO1TRa-hICs8oF7vnlFiCDnMO2Kgt_NKLDpvE3apafxx8a4PIFNc1EUjA6kZzCVjILgksTrZOUDqZP2AdpEMPU4Vg2v-IxZSqEY0arQsAtMkdESS437QvDoa-UJhMv0Rid27HUAKgkKA7yVZCsC_n1xiOm-cqGD_jei_iAakDPnBQdX678UG9kJmcuyj__C8tPmRnRVZwt1peaMqo-Z2xISMH3BzxI1S2HrLgiSp4epUo3nAFfN1M0ugQdK8mTKSzBjxCeL13-bQa7vaAqtFjrMQrwTlRJpL1tUQKjC_nrjgYY4sObO8FokbFx9rH_aPH9I0IXrd2lFktTMRtp0ETSmzc7FKyzMLZRxAP6x84Mv3hXmT82e96LbE4maeFJTkaILrV8e03x-CetgcsIzCN9PvQdTQqcUw9Ml-GxL1896zBje5lwEZEtDXVyfpwr-cE8NGiRp59dE2Fs47ogMgZsHJqpYJlimj2lP2ExgHYgogsNOj9yM7YxlbVJpLlo5RtynA6GWzLnV9BSSjrkXBM444SZILrx2-rBSDeAlQH4ViYa16EHunLPXyWBzCxth2ubmoAkqxsPTr-fa6JjoZlWecg0QH6H6PTXVd01QwS68Bbwrcj8n35LLNaWVm5Dpy46lMzPaYFJlW4dpXVRJ2WVkLnTyPdsnWIqQ22K4xeZP1mTxZPf-XYVC6eHD5PBQmx8cUiqYLe0WA9pvtKwkfLjAuGlZbm-N6SMgs1Wcik2dlFL15TDJJv58DHxZcEGk5RNz4daVQNQLMyav5AhcwF8wC20AcjS0pjsEKGXPXKur7CtyfkPHA0MBlDEZre6nenkXo6jp-ZTgqxYJCXZXgZqLX9Qw9tibmt1Sf9x85XaAkq7hXikPZdHyWczjdS4YA-3gSnwpJ5gS-0tetWag6fkzkI4qHFMg9UrNXGVxrxsEUH9Jbwj49VJAJkgSJWVJgOSPtKPPwzAiSMWWttiFTVCVLXB3tbn-kHMUlvlf_zlTyS2HXHFyIZpqTpwyco6LyST7PBvJan_c99eAGmkOW5Yzua_EeVwSOlHs9s-1cDxkxGPVyz3GXRm_T1qKZ68ILQtUc8c8hNbvgbn7ctnkSIMHSzHoBw0rHaMRX1KDB3j-s-3Uys9myyChiqufM4L9V5aaXlnN91mv4vPURzIVS5TReWqjN7z7lm4M8WgcjkDj9Rvx60qD73CDkJLy77uFT6iJXKDneM1YSKse4r20zQ0OkwcDjb7iEowcqHgvx5KEppKdBWccZWVNHJXZl-tfGI5lWbDPwuWuEK64RIXZJe6JykSphNbWzz5oSp4aMqv4MFWggcKdYkVrlGovI3EpLElDHqBswUUxNJ2JWyJfdtWujOWmNrhpKZbq6EvqrqFd94X2Ay5D_Xz3EO4jRJZhbw4uRUAlrFDRoBUtZ0gFeL-N6ab6_sVdR3U6BV1hchCT-v7Zbt5No_4ULgQ4xb4QYqHL3DVwqfm8UPlGhivAc5n8QFjv-e86xERdWI39x7fE6v2oWCzLmQKW5GBX7ohbbQyOU3c96Haa-N2EQOjms5pQfa4-YJ5E_o4n6LSLtprIfY-3O316UfQNTvbsSkYv447LwoyS-9sHBklvC8RbN36s71UOrCLbGk9S6ypfxnIRYPmrhpd1wHT_jB0fCqQJZwgI5mILYqXnH-uqoHKjUqSPgHnhzT-iVqVSBE6Zq8xqUut-LqESULZ81A35SiGwlYrIQy5dHs5wadUIdbNz1ZWWI2ZybVTE39Ukv1DQp9MrhmYJZYrapTpguEN2me-EBjNNnpLRDsO86eSQAhVzV9J000jIvXxGdlUo3SKwZfM-1P0L2CdhicIgI7-KVSGrpJPxQA00Keey2Oj4P6Vdzsrp362WNlkuMIqueVSfRl8P63JzASuXCRlPwDKZ19D15h36uiyvgtBsKhPeAbzGfM7UTLFU-q5vP1gHgpiLqs6Bw61oo7E51yTu6zrmHukuao-AOGhKbctckfrvrVuZ7PpxD_tuQCoYeHUCW8-cjsh8rVsaA0TOo8g_TGpM-c47gXMYjUbfoo-mJV2hBZSW4a3npoZMgCCgPchFzJONFqs7VEcaVS6a6oXDl3woqq0v_LzNLfoGll6ixi9c5okjLeTvf3z6MROAabvxedMD8u8dkLqvL86q7d4FDrvBZDM8E5DbryvvVRPp9rfSa7KLwInjrM9bzpnV4e7TTk7-LDKg54YU8GF_RLC2vIdOvCRGE23BfG2KZVZof3rmhMITLEbGCSL9zd34d2YXhdqbOsTJ2DaZq_Nwii1lx5RBSf_6RSKyPwm0Q7vP30QKAE6FBMHqr2CQwsldDC9R-nI9Y_FNIrbo03lkz7TQe66pBOCUL22IXO1tcdw6PHnowVfOoI_pzrEAwP66gwnTC7Ysb7hREsTH9SIO-EZvPAb_045jovUfYTQmdYZmTgyr-zPzWn-jkprYnHEUX82Hn7LN3cTjRRNvhH9ELSmfrWYhRaW2Q==","type":"reasoning"},{"arguments":"\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"","call_id":"call_ewLJJaD4OO6pdsTnaDtMuNn0","name":"weather","type":"function_call"},{"call_id":"call_ewLJJaD4OO6pdsTnaDtMuNn0","output":"40 C","type":"function_call_output"}],"model":"o4-mini","reasoning":{"effort":"high","summary":"auto"},"tool_choice":"auto","tools":[{"strict":false,"parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"},"name":"weather","description":"Get weather information for a location","type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://api.openai.com/v1/responses
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |-
+ {
+ "id": "resp_00f45739b037a2600168f239bbb9188196b53e629e83c81309",
+ "object": "response",
+ "created_at": 1760704955,
+ "status": "completed",
+ "background": false,
+ "billing": {
+ "payer": "developer"
+ },
+ "error": null,
+ "incomplete_details": null,
+ "instructions": null,
+ "max_output_tokens": null,
+ "max_tool_calls": null,
+ "model": "o4-mini-2025-04-16",
+ "output": [
+ {
+ "id": "msg_00f45739b037a2600168f239bc36348196b6b0cfe62701d820",
+ "type": "message",
+ "status": "completed",
+ "content": [
+ {
+ "type": "output_text",
+ "annotations": [],
+ "logprobs": [],
+ "text": "It\u2019s currently 40\u00b0C in Florence, Italy."
+ }
+ ],
+ "role": "assistant"
+ }
+ ],
+ "parallel_tool_calls": true,
+ "previous_response_id": null,
+ "prompt_cache_key": null,
+ "reasoning": {
+ "effort": "high",
+ "summary": "detailed"
+ },
+ "safety_identifier": null,
+ "service_tier": "default",
+ "store": false,
+ "temperature": 1.0,
+ "text": {
+ "format": {
+ "type": "text"
+ },
+ "verbosity": "medium"
+ },
+ "tool_choice": "auto",
+ "tools": [
+ {
+ "type": "function",
+ "description": "Get weather information for a location",
+ "name": "weather",
+ "parameters": {
+ "properties": {
+ "location": {
+ "description": "the city",
+ "type": "string"
+ }
+ },
+ "required": [
+ "location"
+ ],
+ "type": "object"
+ },
+ "strict": false
+ }
+ ],
+ "top_logprobs": 0,
+ "top_p": 1.0,
+ "truncation": "disabled",
+ "usage": {
+ "input_tokens": 1406,
+ "input_tokens_details": {
+ "cached_tokens": 1152
+ },
+ "output_tokens": 15,
+ "output_tokens_details": {
+ "reasoning_tokens": 0
+ },
+ "total_tokens": 1421
+ },
+ "user": null,
+ "metadata": {}
+ }
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 972.409834ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/multi_tool.yaml
new file mode 100644
index 000000000..4d3d6adf3
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 855
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1758884877-DsUZ3N2CGkZT131vUNCm\",\"provider\":\"Google\",\"model\":\"anthropic/claude-sonnet-4\",\"object\":\"chat.completion\",\"created\":1758884877,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"I'll add and multiply the numbers 2 and 3 for you.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"id\":\"toolu_vrtx_01J7uVChiFATMdceHtZbaR82\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"add\",\"arguments\":\"{\\\"a\\\": 2, \\\"b\\\": 3}\"}},{\"id\":\"toolu_vrtx_0141TPmACbTafQPicKQEJu3R\",\"index\":1,\"type\":\"function\",\"function\":{\"name\":\"multiply\",\"arguments\":\"{\\\"a\\\": 2, \\\"b\\\": 3}\"}}]}}],\"usage\":{\"prompt_tokens\":507,\"completion_tokens\":137,\"total_tokens\":644,\"cost\":0.003576,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.001521,\"upstream_inference_completions_cost\":0.002055},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.669959042s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1373
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"I''ll add and multiply the numbers 2 and 3 for you.","tool_calls":[{"id":"toolu_vrtx_01J7uVChiFATMdceHtZbaR82","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"toolu_vrtx_0141TPmACbTafQPicKQEJu3R","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"toolu_vrtx_01J7uVChiFATMdceHtZbaR82","role":"tool"},{"content":"6","tool_call_id":"toolu_vrtx_0141TPmACbTafQPicKQEJu3R","role":"tool"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n{\"id\":\"gen-1758884880-aGZsNsK0GXnJIkEUDHHR\",\"provider\":\"Google\",\"model\":\"anthropic/claude-sonnet-4\",\"object\":\"chat.completion\",\"created\":1758884880,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The results are:\\n- Adding 2 + 3 = 5\\n- Multiplying 2 Ć 3 = 6\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":705,\"completion_tokens\":35,\"total_tokens\":740,\"cost\":0.00264,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.002115,\"upstream_inference_completions_cost\":0.000525},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.727566042s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/multi_tool_streaming.yaml
new file mode 100644
index 000000000..579cd22ea
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/multi_tool_streaming.yaml
@@ -0,0 +1,133 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 892
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":"I'll add an","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":"d multiply the numbers","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":" 2 and 3 for","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":" you.","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"toolu_vrtx_019HCkvBaE95VcC6dm247tua","index":0,"type":"function","function":{"name":"add","arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"{\"a"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"\": 2"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":", \"b\": "}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"3}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"toolu_vrtx_01BzTvcZwg8uFyS2ZbyfFbbg","index":1,"type":"function","function":{"name":"multiply","arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"type":"function","function":{"arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"type":"function","function":{"arguments":"{\"a\": 2"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"type":"function","function":{"arguments":", \"b\": 3}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}]}
+
+ data: {"id":"gen-1758884882-qvQRbKQ9pvC3XNTxxfOe","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884882,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":502,"completion_tokens":137,"total_tokens":639,"cost":0.003561,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.001506,"upstream_inference_completions_cost":0.002055},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.209197084s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1410
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"I''ll add and multiply the numbers 2 and 3 for you.","tool_calls":[{"id":"toolu_vrtx_019HCkvBaE95VcC6dm247tua","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"toolu_vrtx_01BzTvcZwg8uFyS2ZbyfFbbg","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"toolu_vrtx_019HCkvBaE95VcC6dm247tua","role":"tool"},{"content":"6","tool_call_id":"toolu_vrtx_01BzTvcZwg8uFyS2ZbyfFbbg","role":"tool"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884885-2kzfkifpNjmBYSZUPnHy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884885,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884885-2kzfkifpNjmBYSZUPnHy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884885,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884885-2kzfkifpNjmBYSZUPnHy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884885,"choices":[{"index":0,"delta":{"role":"assistant","content":"The","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884885-2kzfkifpNjmBYSZUPnHy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884885,"choices":[{"index":0,"delta":{"role":"assistant","content":" results","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884885-2kzfkifpNjmBYSZUPnHy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884885,"choices":[{"index":0,"delta":{"role":"assistant","content":" are","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884885-2kzfkifpNjmBYSZUPnHy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884885,"choices":[{"index":0,"delta":{"role":"assistant","content":":\n- Adding","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884885-2kzfkifpNjmBYSZUPnHy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884885,"choices":[{"index":0,"delta":{"role":"assistant","content":" 2 +","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884885-2kzfkifpNjmBYSZUPnHy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884885,"choices":[{"index":0,"delta":{"role":"assistant","content":" 3 = 5\n-","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884885-2kzfkifpNjmBYSZUPnHy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884885,"choices":[{"index":0,"delta":{"role":"assistant","content":" Multiplying 2 Ć ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884885-2kzfkifpNjmBYSZUPnHy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884885,"choices":[{"index":0,"delta":{"role":"assistant","content":"3 = 6","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884885-2kzfkifpNjmBYSZUPnHy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884885,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884885-2kzfkifpNjmBYSZUPnHy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884885,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1758884885-2kzfkifpNjmBYSZUPnHy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884885,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":700,"completion_tokens":35,"total_tokens":735,"cost":0.002625,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0021,"upstream_inference_completions_cost":0.000525},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.846005584s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/simple.yaml
new file mode 100644
index 000000000..ea66e8a02
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 200
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n{\"id\":\"gen-1758884862-nNnfpZfNjYv7wX3JRgcl\",\"provider\":\"Google\",\"model\":\"anthropic/claude-sonnet-4\",\"object\":\"chat.completion\",\"created\":1758884862,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"OlĆ”! \\n\\n(That's \\\"hi\\\" in Portuguese!)\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":16,\"completion_tokens\":18,\"total_tokens\":34,\"cost\":0.000318,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.000048,\"upstream_inference_completions_cost\":0.00027},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.835014334s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/simple_streaming.yaml
new file mode 100644
index 000000000..72c9ad65a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/simple_streaming.yaml
@@ -0,0 +1,46 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 254
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884864-Ti76q8ykUk3txETvMAqx","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884864,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884864-Ti76q8ykUk3txETvMAqx","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884864,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884864-Ti76q8ykUk3txETvMAqx","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884864,"choices":[{"index":0,"delta":{"role":"assistant","content":"OlĆ”!","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884864-Ti76q8ykUk3txETvMAqx","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884864,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884864-Ti76q8ykUk3txETvMAqx","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884864,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1758884864-Ti76q8ykUk3txETvMAqx","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884864,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":16,"completion_tokens":7,"total_tokens":23,"cost":0.000153,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.000048,"upstream_inference_completions_cost":0.000105},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.099917792s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/tool.yaml
new file mode 100644
index 000000000..7b83f4351
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 492
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n{\"id\":\"gen-1758884867-bIgRXBqY3sA7T7hlXQLZ\",\"provider\":\"Google\",\"model\":\"anthropic/claude-sonnet-4\",\"object\":\"chat.completion\",\"created\":1758884867,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"I'll get the weather information for Florence, Italy for you.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"id\":\"toolu_vrtx_01AFJ7sm96FNbLYnwvJgtjjR\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\": \\\"Florence,Italy\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":394,\"completion_tokens\":67,\"total_tokens\":461,\"cost\":0.002187,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.001182,\"upstream_inference_completions_cost\":0.001005},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.244292667s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 830
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"I''ll get the weather information for Florence, Italy for you.","tool_calls":[{"id":"toolu_vrtx_01AFJ7sm96FNbLYnwvJgtjjR","function":{"arguments":"{\"location\": \"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"toolu_vrtx_01AFJ7sm96FNbLYnwvJgtjjR","role":"tool"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1758884868-S2ViWydCwMw4IRUnQe3o\",\"provider\":\"Google\",\"model\":\"anthropic/claude-sonnet-4\",\"object\":\"chat.completion\",\"created\":1758884868,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The current weather in Florence, Italy shows a temperature of 40°C (104°F). That's quite hot! If you're planning to visit or are currently there, make sure to stay hydrated and seek shade during the hottest parts of the day.\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":476,\"completion_tokens\":57,\"total_tokens\":533,\"cost\":0.002283,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.001428,\"upstream_inference_completions_cost\":0.000855},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.084771333s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/tool_streaming.yaml
new file mode 100644
index 000000000..4a7a46a7e
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/claude-sonnet-4/tool_streaming.yaml
@@ -0,0 +1,131 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 546
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884871-ydnydgzKdJZqqueHDHG5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884871,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884871-ydnydgzKdJZqqueHDHG5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884871,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884871-ydnydgzKdJZqqueHDHG5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884871,"choices":[{"index":0,"delta":{"role":"assistant","content":"I'll get the weather information for Florence","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884871-ydnydgzKdJZqqueHDHG5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884871,"choices":[{"index":0,"delta":{"role":"assistant","content":", Italy for you.","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884871-ydnydgzKdJZqqueHDHG5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884871,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884871-ydnydgzKdJZqqueHDHG5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884871,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"toolu_vrtx_01RbqWDZJV2wefF6PD6oi6rq","index":0,"type":"function","function":{"name":"weather","arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884871-ydnydgzKdJZqqueHDHG5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884871,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884871-ydnydgzKdJZqqueHDHG5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884871,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"{\"location"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884871-ydnydgzKdJZqqueHDHG5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884871,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"\": \"Flor"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884871-ydnydgzKdJZqqueHDHG5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884871,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"en"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884871-ydnydgzKdJZqqueHDHG5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884871,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"ce,Italy\"}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884871-ydnydgzKdJZqqueHDHG5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884871,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884871-ydnydgzKdJZqqueHDHG5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884871,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}]}
+
+ data: {"id":"gen-1758884871-ydnydgzKdJZqqueHDHG5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884871,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":394,"completion_tokens":67,"total_tokens":461,"cost":0.002187,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.001182,"upstream_inference_completions_cost":0.001005},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.614987417s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 884
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"I''ll get the weather information for Florence, Italy for you.","tool_calls":[{"id":"toolu_vrtx_01RbqWDZJV2wefF6PD6oi6rq","function":{"arguments":"{\"location\": \"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"toolu_vrtx_01RbqWDZJV2wefF6PD6oi6rq","role":"tool"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":"The","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":" current","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":" weather in Florence, Italy is 40","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":"°C (104°F). That","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":"'s quite","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":" hot","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":"! Make","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":" sure to","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":" stay","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":" hydrated and seek","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":" shade if","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":" you're planning","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":" to be out","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":"doors.","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1758884875-M9WzCwVeN4gqbY9Y1cW5","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1758884875,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":476,"completion_tokens":43,"total_tokens":519,"cost":0.002073,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.001428,"upstream_inference_completions_cost":0.000645},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.845872166s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/multi_tool.yaml
new file mode 100644
index 000000000..95b610f52
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 862
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"deepseek/deepseek-chat-v3.1:free","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1758885224-g5oXqGRqim44ZJGGod8I\",\"provider\":\"DeepInfra\",\"model\":\"deepseek/deepseek-chat-v3.1:free\",\"object\":\"chat.completion\",\"created\":1758885224,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"I'll add and multiply the numbers 2 and 3 simultaneously as requested.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_0656\",\"function\":{\"arguments\":\"{\\\"a\\\": 2, \\\"b\\\": 3}\",\"name\":\"add\"},\"type\":\"function\"},{\"index\":1,\"id\":\"call_5236\",\"function\":{\"arguments\":\"{\\\"a\\\": 2, \\\"b\\\": 3}\",\"name\":\"multiply\"},\"type\":\"function\"}]}}],\"usage\":{\"prompt_tokens\":256,\"completion_tokens\":52,\"total_tokens\":308,\"cost\":0,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0,\"upstream_inference_completions_cost\":0},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 619.225375ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1296
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"I''ll add and multiply the numbers 2 and 3 simultaneously as requested.","tool_calls":[{"id":"call_0656","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"call_5236","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"call_0656","role":"tool"},{"content":"6","tool_call_id":"call_5236","role":"tool"}],"model":"deepseek/deepseek-chat-v3.1:free","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1758885229-rCHLKXJniwXh0QybzWF4\",\"provider\":\"DeepInfra\",\"model\":\"deepseek/deepseek-chat-v3.1:free\",\"object\":\"chat.completion\",\"created\":1758885229,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The sum of 2 and 3 is 5, and the product of 2 and 3 is 6.\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":316,\"completion_tokens\":26,\"total_tokens\":342,\"cost\":0,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0,\"upstream_inference_completions_cost\":0},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 950.99525ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/multi_tool_streaming.yaml
new file mode 100644
index 000000000..c9165f2eb
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/multi_tool_streaming.yaml
@@ -0,0 +1,127 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 899
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"deepseek/deepseek-chat-v3.1:free","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758885164-b2FtWHeaqgFVXp8PSZCZ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885164,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885164-b2FtWHeaqgFVXp8PSZCZ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885164,"choices":[{"index":0,"delta":{"role":"assistant","content":"I","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885164-b2FtWHeaqgFVXp8PSZCZ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885164,"choices":[{"index":0,"delta":{"role":"assistant","content":"'ll add","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885164-b2FtWHeaqgFVXp8PSZCZ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885164,"choices":[{"index":0,"delta":{"role":"assistant","content":" and multiply","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885164-b2FtWHeaqgFVXp8PSZCZ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885164,"choices":[{"index":0,"delta":{"role":"assistant","content":" the","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885164-b2FtWHeaqgFVXp8PSZCZ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885164,"choices":[{"index":0,"delta":{"role":"assistant","content":" numbers ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885164-b2FtWHeaqgFVXp8PSZCZ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885164,"choices":[{"index":0,"delta":{"role":"assistant","content":"2 and","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885164-b2FtWHeaqgFVXp8PSZCZ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885164,"choices":[{"index":0,"delta":{"role":"assistant","content":" 3","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885164-b2FtWHeaqgFVXp8PSZCZ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885164,"choices":[{"index":0,"delta":{"role":"assistant","content":" simultaneously for","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885164-b2FtWHeaqgFVXp8PSZCZ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885164,"choices":[{"index":0,"delta":{"role":"assistant","content":" you.","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885164-b2FtWHeaqgFVXp8PSZCZ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885164,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"call_9953","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885164-b2FtWHeaqgFVXp8PSZCZ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885164,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"id":"call_1453","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885164-b2FtWHeaqgFVXp8PSZCZ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885164,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}]}
+
+ data: {"id":"gen-1758885164-b2FtWHeaqgFVXp8PSZCZ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885164,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":250,"completion_tokens":52,"total_tokens":302,"cost":0,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 759.0745ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1328
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"I''ll add and multiply the numbers 2 and 3 simultaneously for you.","tool_calls":[{"id":"call_9953","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"call_1453","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"call_9953","role":"tool"},{"content":"6","tool_call_id":"call_1453","role":"tool"}],"model":"deepseek/deepseek-chat-v3.1:free","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":"The","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":" addition of","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":" 2","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":" and ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":"3 gives","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":":","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":"5\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":"The multiplication","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":" of ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":"2 and","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":" 3","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":" gives:","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":" 6","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1758885174-21jFczhB62eYMTvgbGCJ","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758885175,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":310,"completion_tokens":26,"total_tokens":336,"cost":0,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 796.350208ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/simple.yaml
new file mode 100644
index 000000000..6b6ff4181
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 207
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"deepseek/deepseek-chat-v3.1:free","max_tokens":4000,"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1758884896-Vxp1md82hWmmqrwPbsR2\",\"provider\":\"DeepInfra\",\"model\":\"deepseek/deepseek-chat-v3.1:free\",\"object\":\"chat.completion\",\"created\":1758884897,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"OlĆ”!\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":13,\"completion_tokens\":4,\"total_tokens\":17,\"cost\":0,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0,\"upstream_inference_completions_cost\":0},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 915.791ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/simple_streaming.yaml
new file mode 100644
index 000000000..c9084a1f9
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/simple_streaming.yaml
@@ -0,0 +1,42 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 261
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"deepseek/deepseek-chat-v3.1:free","max_tokens":4000,"stream_options":{"include_usage":true},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884899-pD8p2SxLbbZqkwAwdyNA","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884899,"choices":[{"index":0,"delta":{"role":"assistant","content":"Ol","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884899-pD8p2SxLbbZqkwAwdyNA","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884899,"choices":[{"index":0,"delta":{"role":"assistant","content":"Ć”!","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884899-pD8p2SxLbbZqkwAwdyNA","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884899,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1758884899-pD8p2SxLbbZqkwAwdyNA","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884899,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":13,"completion_tokens":4,"total_tokens":17,"cost":0,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 910.04ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/tool.yaml
new file mode 100644
index 000000000..10e2176ae
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 499
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"deepseek/deepseek-chat-v3.1:free","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1758884901-AhRCWiXrgjl5bfbRbufi\",\"provider\":\"DeepInfra\",\"model\":\"deepseek/deepseek-chat-v3.1:free\",\"object\":\"chat.completion\",\"created\":1758884901,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"I'll check the weather in Florence, Italy for you.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_9a0a\",\"function\":{\"arguments\":\"{\\\"location\\\": \\\"Florence\\\"}\",\"name\":\"weather\"},\"type\":\"function\"}]}}],\"usage\":{\"prompt_tokens\":160,\"completion_tokens\":27,\"total_tokens\":187,\"cost\":0,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0,\"upstream_inference_completions_cost\":0},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 943.849167ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 768
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"I''ll check the weather in Florence, Italy for you.","tool_calls":[{"id":"call_9a0a","function":{"arguments":"{\"location\": \"Florence\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_9a0a","role":"tool"}],"model":"deepseek/deepseek-chat-v3.1:free","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1758884904-QNeUMpghodvaCtyHio9W\",\"provider\":\"DeepInfra\",\"model\":\"deepseek/deepseek-chat-v3.1:free\",\"object\":\"chat.completion\",\"created\":1758884905,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The current temperature in Florence, Italy is **40°C** (104°F). That's quite hot! It appears to be a very warm day there. You might want to stay hydrated and seek shade if you're planning to be outdoors.\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":192,\"completion_tokens\":51,\"total_tokens\":243,\"cost\":0,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0,\"upstream_inference_completions_cost\":0},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 507.301334ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/tool_streaming.yaml
new file mode 100644
index 000000000..29f6c4a72
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/deepseek-chat-v3.1-free/tool_streaming.yaml
@@ -0,0 +1,151 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 553
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"deepseek/deepseek-chat-v3.1:free","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884909-lcWlYG0HEPzjNnyrY6Ak","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884909,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884909-lcWlYG0HEPzjNnyrY6Ak","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884909,"choices":[{"index":0,"delta":{"role":"assistant","content":"I","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884909-lcWlYG0HEPzjNnyrY6Ak","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884909,"choices":[{"index":0,"delta":{"role":"assistant","content":"'ll check","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884909-lcWlYG0HEPzjNnyrY6Ak","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884909,"choices":[{"index":0,"delta":{"role":"assistant","content":" the weather","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884909-lcWlYG0HEPzjNnyrY6Ak","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884909,"choices":[{"index":0,"delta":{"role":"assistant","content":" in","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884909-lcWlYG0HEPzjNnyrY6Ak","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884909,"choices":[{"index":0,"delta":{"role":"assistant","content":" Florence,","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884909-lcWlYG0HEPzjNnyrY6Ak","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884909,"choices":[{"index":0,"delta":{"role":"assistant","content":" Italy for","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884909-lcWlYG0HEPzjNnyrY6Ak","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884909,"choices":[{"index":0,"delta":{"role":"assistant","content":" you.","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884909-lcWlYG0HEPzjNnyrY6Ak","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884909,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"call_3cac","function":{"arguments":"{\"location\": \"Florence\"}","name":"weather"},"type":"function"}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884909-lcWlYG0HEPzjNnyrY6Ak","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884909,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}]}
+
+ data: {"id":"gen-1758884909-lcWlYG0HEPzjNnyrY6Ak","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884909,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":160,"completion_tokens":27,"total_tokens":187,"cost":0,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 898.243ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 822
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"I''ll check the weather in Florence, Italy for you.","tool_calls":[{"id":"call_3cac","function":{"arguments":"{\"location\": \"Florence\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_3cac","role":"tool"}],"model":"deepseek/deepseek-chat-v3.1:free","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":"The","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" current","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" weather","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" in Florence","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":", Italy","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" is ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":"40°","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":"C (","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":"104°","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":"F).","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" That","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":"'s quite","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" hot!","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" If","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" you're","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" planning","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" to visit","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" or","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" are","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" currently","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" there,","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" make sure","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" to stay","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" hydrated and","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" seek shade","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" during the","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" hottest parts","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" of the","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":" day.","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1758884912-RP1NFdMIPDp14zRR1slx","provider":"DeepInfra","model":"deepseek/deepseek-chat-v3.1:free","object":"chat.completion.chunk","created":1758884912,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":192,"completion_tokens":50,"total_tokens":242,"cost":0,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 800.502916ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/multi_tool.yaml
new file mode 100644
index 000000000..9733106bc
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 853
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n{\"id\":\"gen-1758884893-RNaA0KwkX5DNRlXi1Q4O\",\"provider\":\"Google\",\"model\":\"google/gemini-2.5-flash\",\"object\":\"chat.completion\",\"created\":1758884893,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"index\":0,\"id\":\"tool_0_add_TCy46s7l5XQ6Mfi91IsM\",\"type\":\"function\",\"function\":{\"name\":\"add\",\"arguments\":\"{\\\"b\\\":3,\\\"a\\\":2}\"}},{\"index\":1,\"id\":\"tool_1_multiply_zdqptJA2dh857K7gsjKs\",\"type\":\"function\",\"function\":{\"name\":\"multiply\",\"arguments\":\"{\\\"b\\\":3,\\\"a\\\":2}\"}}]}}],\"usage\":{\"prompt_tokens\":60,\"completion_tokens\":10,\"total_tokens\":70,\"cost\":0.000043,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.000018,\"upstream_inference_completions_cost\":0.000025},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 940.752083ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1296
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"tool_0_add_TCy46s7l5XQ6Mfi91IsM","function":{"arguments":"{\"b\":3,\"a\":2}","name":"add"},"type":"function"},{"id":"tool_1_multiply_zdqptJA2dh857K7gsjKs","function":{"arguments":"{\"b\":3,\"a\":2}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"tool_0_add_TCy46s7l5XQ6Mfi91IsM","role":"tool"},{"content":"6","tool_call_id":"tool_1_multiply_zdqptJA2dh857K7gsjKs","role":"tool"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n{\"id\":\"gen-1758884894-7bHlyhWUTzdBiRAUFya6\",\"provider\":\"Google\",\"model\":\"google/gemini-2.5-flash\",\"object\":\"chat.completion\",\"created\":1758884894,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The sum of 2 and 3 is 5, and the product of 2 and 3 is 6.\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":116,\"completion_tokens\":25,\"total_tokens\":141,\"cost\":0.0000973,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000348,\"upstream_inference_completions_cost\":0.0000625},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 713.652834ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/multi_tool_streaming.yaml
new file mode 100644
index 000000000..fb69ab0bf
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/multi_tool_streaming.yaml
@@ -0,0 +1,77 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 890
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884895-ZW7V1SBC3XRGQDgz6cog","provider":"Google","model":"google/gemini-2.5-flash","object":"chat.completion.chunk","created":1758884895,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"tool_0_add_3sQISwQkKIrHMDRRTqmB","type":"function","function":{"name":"add","arguments":"{\"b\":3,\"a\":2}"}},{"index":1,"id":"tool_1_multiply_nZSCK8smzKFKbdiORQio","type":"function","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"}}]},"finish_reason":"tool_calls","native_finish_reason":"STOP","logprobs":null}]}
+
+ data: {"id":"gen-1758884895-ZW7V1SBC3XRGQDgz6cog","provider":"Google","model":"google/gemini-2.5-flash","object":"chat.completion.chunk","created":1758884895,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":57,"completion_tokens":10,"total_tokens":67,"cost":0.0000421,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000171,"upstream_inference_completions_cost":0.000025},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 878.667625ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1333
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"tool_0_add_3sQISwQkKIrHMDRRTqmB","function":{"arguments":"{\"b\":3,\"a\":2}","name":"add"},"type":"function"},{"id":"tool_1_multiply_nZSCK8smzKFKbdiORQio","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"tool_0_add_3sQISwQkKIrHMDRRTqmB","role":"tool"},{"content":"6","tool_call_id":"tool_1_multiply_nZSCK8smzKFKbdiORQio","role":"tool"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884896-S4C9WkpsADy97egk3ecX","provider":"Google","model":"google/gemini-2.5-flash","object":"chat.completion.chunk","created":1758884896,"choices":[{"index":0,"delta":{"role":"assistant","content":"The sum of","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884896-S4C9WkpsADy97egk3ecX","provider":"Google","model":"google/gemini-2.5-flash","object":"chat.completion.chunk","created":1758884896,"choices":[{"index":0,"delta":{"role":"assistant","content":" 2 and 3 is 5, and the product of 2 and 3","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884896-S4C9WkpsADy97egk3ecX","provider":"Google","model":"google/gemini-2.5-flash","object":"chat.completion.chunk","created":1758884896,"choices":[{"index":0,"delta":{"role":"assistant","content":" is 6.","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"STOP","logprobs":null}]}
+
+ data: {"id":"gen-1758884896-S4C9WkpsADy97egk3ecX","provider":"Google","model":"google/gemini-2.5-flash","object":"chat.completion.chunk","created":1758884896,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":111,"completion_tokens":25,"total_tokens":136,"cost":0.0000958,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000333,"upstream_inference_completions_cost":0.0000625},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 652.719208ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/simple.yaml
new file mode 100644
index 000000000..b40ce56f7
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 198
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n{\"id\":\"gen-1758884888-8cFWFhyuZpFJzRBAfJhE\",\"provider\":\"Google\",\"model\":\"google/gemini-2.5-flash\",\"object\":\"chat.completion\",\"created\":1758884888,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"OlĆ”!\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":9,\"completion_tokens\":2,\"total_tokens\":11,\"cost\":0.0000077,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000027,\"upstream_inference_completions_cost\":0.000005},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 643.525875ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/simple_streaming.yaml
new file mode 100644
index 000000000..7c8d18804
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/simple_streaming.yaml
@@ -0,0 +1,42 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 252
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"stream_options":{"include_usage":true},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884889-wBMEuVgepAaRbPTJBSmM","provider":"Google","model":"google/gemini-2.5-flash","object":"chat.completion.chunk","created":1758884889,"choices":[{"index":0,"delta":{"role":"assistant","content":"\"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884889-wBMEuVgepAaRbPTJBSmM","provider":"Google","model":"google/gemini-2.5-flash","object":"chat.completion.chunk","created":1758884889,"choices":[{"index":0,"delta":{"role":"assistant","content":"OlĆ”\" or \"Oi","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884889-wBMEuVgepAaRbPTJBSmM","provider":"Google","model":"google/gemini-2.5-flash","object":"chat.completion.chunk","created":1758884889,"choices":[{"index":0,"delta":{"role":"assistant","content":"\"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"STOP","logprobs":null}]}
+
+ data: {"id":"gen-1758884889-wBMEuVgepAaRbPTJBSmM","provider":"Google","model":"google/gemini-2.5-flash","object":"chat.completion.chunk","created":1758884889,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":9,"completion_tokens":7,"total_tokens":16,"cost":0.0000202,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000027,"upstream_inference_completions_cost":0.0000175},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 969.074167ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/tool.yaml
new file mode 100644
index 000000000..b0131ae39
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 490
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n{\"id\":\"gen-1758884890-eb63mHbHPmNmDzud29uQ\",\"provider\":\"Google\",\"model\":\"google/gemini-2.5-flash\",\"object\":\"chat.completion\",\"created\":1758884890,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"index\":0,\"id\":\"tool_0_weather_tpb31y4AAKTQomEE5Gds\",\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\":\\\"Florence,Italy\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":28,\"completion_tokens\":5,\"total_tokens\":33,\"cost\":0.0000209,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000084,\"upstream_inference_completions_cost\":0.0000125},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 920.856208ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 753
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"tool_0_weather_tpb31y4AAKTQomEE5Gds","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"tool_0_weather_tpb31y4AAKTQomEE5Gds","role":"tool"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n{\"id\":\"gen-1758884890-CHMiuxRWBS7OxuQFUsla\",\"provider\":\"Google\",\"model\":\"google/gemini-2.5-flash\",\"object\":\"chat.completion\",\"created\":1758884891,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The weather in Florence, Italy is 40 degrees Celsius.\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":57,\"completion_tokens\":13,\"total_tokens\":70,\"cost\":0.0000496,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000171,\"upstream_inference_completions_cost\":0.0000325},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 739.272167ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/tool_streaming.yaml
new file mode 100644
index 000000000..50d028a4b
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-2.5-flash/tool_streaming.yaml
@@ -0,0 +1,75 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 544
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884891-TdXi6e4P1LOAy1d2zvUP","provider":"Google","model":"google/gemini-2.5-flash","object":"chat.completion.chunk","created":1758884891,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"tool_0_weather_gNpQBlUfofhGF4jueDU7","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence,Italy\"}"}}]},"finish_reason":"tool_calls","native_finish_reason":"STOP","logprobs":null}]}
+
+ data: {"id":"gen-1758884891-TdXi6e4P1LOAy1d2zvUP","provider":"Google","model":"google/gemini-2.5-flash","object":"chat.completion.chunk","created":1758884891,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":28,"completion_tokens":5,"total_tokens":33,"cost":0.0000209,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000084,"upstream_inference_completions_cost":0.0000125},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 760.496ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 807
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"tool_0_weather_gNpQBlUfofhGF4jueDU7","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"tool_0_weather_gNpQBlUfofhGF4jueDU7","role":"tool"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884892-mxDweeTvpL2t8FqL5Y6k","provider":"Google","model":"google/gemini-2.5-flash","object":"chat.completion.chunk","created":1758884892,"choices":[{"index":0,"delta":{"role":"assistant","content":"The weather in Florence, Italy","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884892-mxDweeTvpL2t8FqL5Y6k","provider":"Google","model":"google/gemini-2.5-flash","object":"chat.completion.chunk","created":1758884892,"choices":[{"index":0,"delta":{"role":"assistant","content":" is 40 degrees Celsius.","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"STOP","logprobs":null}]}
+
+ data: {"id":"gen-1758884892-mxDweeTvpL2t8FqL5Y6k","provider":"Google","model":"google/gemini-2.5-flash","object":"chat.completion.chunk","created":1758884892,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":55,"completion_tokens":13,"total_tokens":68,"cost":0.000049,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000165,"upstream_inference_completions_cost":0.0000325},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 736.252583ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/multi_tool.yaml
new file mode 100644
index 000000000..dd06f30e1
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 857
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1763546723-krpNoMGltmXXMt7QEkBX\",\"provider\":\"Google\",\"model\":\"google/gemini-3-pro-preview\",\"object\":\"chat.completion\",\"created\":1763546723,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":\"**Contemplating Dual Operations**\\n\\nI'm now zeroing in on the core requirement: simultaneously executing addition and multiplication on the given numbers, 2 and 3. The key constraint is to invoke both functions in a single go. I'm focusing on the mechanics of achieving this concurrent tool usage.\\n\\n\\n**Refining Concurrent Tool Calls**\\n\\nCurrently, I'm working to consolidate the add and multiply functions into a single step. The task's essential characteristic is the simultaneous use of both tools on the provided inputs, which are 2 and 3. My next iteration will involve generating the necessary tool calls to achieve this concurrent operation.\\n\\n\\n\",\"tool_calls\":[{\"index\":0,\"id\":\"tool_add_Rr5wzukrmPeay1Ei7Ab0\",\"type\":\"function\",\"function\":{\"name\":\"add\",\"arguments\":\"{\\\"a\\\":2,\\\"b\\\":3}\"}},{\"index\":1,\"id\":\"tool_multiply_XXecV033QPQiOE0Pid5S\",\"type\":\"function\",\"function\":{\"name\":\"multiply\",\"arguments\":\"{\\\"a\\\":2,\\\"b\\\":3}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"**Contemplating Dual Operations**\\n\\nI'm now zeroing in on the core requirement: simultaneously executing addition and multiplication on the given numbers, 2 and 3. The key constraint is to invoke both functions in a single go. I'm focusing on the mechanics of achieving this concurrent tool usage.\\n\\n\\n**Refining Concurrent Tool Calls**\\n\\nCurrently, I'm working to consolidate the add and multiply functions into a single step. The task's essential characteristic is the simultaneous use of both tools on the provided inputs, which are 2 and 3. My next iteration will involve generating the necessary tool calls to achieve this concurrent operation.\\n\\n\\n\",\"format\":\"google-gemini-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"CiQB4/H/XgkUpJU4QU+IXqZeUmdE5p7/0hlWhrR4hblxPtdT+FoKdgHj8f9eh5vsZhTaF6ubhhFu/tYEEcc2uRhpehbecLT49gx/k4uXNEMWcVIdnlyUmOWB5mUoL0TCRHLXcs/HdbUgt41TfJiLLFzsIJOu6WLLRD61pEKXNg8lbOqbNiy4QZxvpkO/VQlLtZ8I8AG6t7POSFnSbkcKgQEB4/H/Xhyqc6U/uyqEYFlwSKlzmYP4plvxiZjznGbdk2NT0Y5MDaX5uoswUPa5h/UUJIZmwjetqYrdlaIV/fKL0wYLkhwLz51xSwe69yKSxN1AitfEFr9damnf2jh+YFMUwvyqPqFsf8evKGTk+6+WkRnY0zgqSN0yYtisjd1ZbrEKlwEB4/H/XhaCkzS66UWyWnxYNwislAPQrh1thGB58ALOZYxbWJNrKoXEpt7auCwEDEnZjRV7hAFGX1F2F5oRbAmgeBy1HRmJmE7MmV4KzQlHQlwYGVPNxohvIFu50Jws53+NYzAhMD+UUdXyvwWstIptgJVeTcbuXnALvn4vKn/7AZJeK0NlqY7q7UBxw4dfuz3nDfGdBjhXCm0B4/H/XifuvCQ5OYGkaUmlT1nvCLsMJXtVldGe2kiFTfZ8793EUQ2a4WT9sFP3t9KYr8rgzndHYCLFKJF/lDCM0wCj5YJbWbEGsJGVw1LAAem8tni/PV6UNHYhbqjsINkibaXkIo4L2rpb3xWICiwB4/H/XhQxGpYF/1hitRT9RPbq3fdS67vM/tDkwalkD/0eZiDq089xuJx/FA==\",\"id\":\"tool_add_Rr5wzukrmPeay1Ei7Ab0\",\"format\":\"google-gemini-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":60,\"completion_tokens\":128,\"total_tokens\":188,\"cost\":0.001656,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00012,\"upstream_inference_completions_cost\":0.001536},\"completion_tokens_details\":{\"reasoning_tokens\":110,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.777893792s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2966
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"tool_add_Rr5wzukrmPeay1Ei7Ab0","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"tool_multiply_XXecV033QPQiOE0Pid5S","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"google-gemini-v1","index":0,"text":"**Contemplating Dual Operations**\n\nI''m now zeroing in on the core requirement: simultaneously executing addition and multiplication on the given numbers, 2 and 3. The key constraint is to invoke both functions in a single go. I''m focusing on the mechanics of achieving this concurrent tool usage.\n\n\n**Refining Concurrent Tool Calls**\n\nCurrently, I''m working to consolidate the add and multiply functions into a single step. The task''s essential characteristic is the simultaneous use of both tools on the provided inputs, which are 2 and 3. My next iteration will involve generating the necessary tool calls to achieve this concurrent operation.\n\n\n","type":"reasoning.text"},{"data":"CiQB4/H/XgkUpJU4QU+IXqZeUmdE5p7/0hlWhrR4hblxPtdT+FoKdgHj8f9eh5vsZhTaF6ubhhFu/tYEEcc2uRhpehbecLT49gx/k4uXNEMWcVIdnlyUmOWB5mUoL0TCRHLXcs/HdbUgt41TfJiLLFzsIJOu6WLLRD61pEKXNg8lbOqbNiy4QZxvpkO/VQlLtZ8I8AG6t7POSFnSbkcKgQEB4/H/Xhyqc6U/uyqEYFlwSKlzmYP4plvxiZjznGbdk2NT0Y5MDaX5uoswUPa5h/UUJIZmwjetqYrdlaIV/fKL0wYLkhwLz51xSwe69yKSxN1AitfEFr9damnf2jh+YFMUwvyqPqFsf8evKGTk+6+WkRnY0zgqSN0yYtisjd1ZbrEKlwEB4/H/XhaCkzS66UWyWnxYNwislAPQrh1thGB58ALOZYxbWJNrKoXEpt7auCwEDEnZjRV7hAFGX1F2F5oRbAmgeBy1HRmJmE7MmV4KzQlHQlwYGVPNxohvIFu50Jws53+NYzAhMD+UUdXyvwWstIptgJVeTcbuXnALvn4vKn/7AZJeK0NlqY7q7UBxw4dfuz3nDfGdBjhXCm0B4/H/XifuvCQ5OYGkaUmlT1nvCLsMJXtVldGe2kiFTfZ8793EUQ2a4WT9sFP3t9KYr8rgzndHYCLFKJF/lDCM0wCj5YJbWbEGsJGVw1LAAem8tni/PV6UNHYhbqjsINkibaXkIo4L2rpb3xWICiwB4/H/XhQxGpYF/1hitRT9RPbq3fdS67vM/tDkwalkD/0eZiDq089xuJx/FA==","format":"google-gemini-v1","id":"tool_add_Rr5wzukrmPeay1Ei7Ab0","index":0,"type":"reasoning.encrypted"}]},{"content":"5","tool_call_id":"tool_add_Rr5wzukrmPeay1Ei7Ab0","role":"tool"},{"content":"6","tool_call_id":"tool_multiply_XXecV033QPQiOE0Pid5S","role":"tool"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n{\"id\":\"gen-1763546727-n3yus1LOuR5HXnN0YHRi\",\"provider\":\"Google AI Studio\",\"model\":\"google/gemini-3-pro-preview\",\"object\":\"chat.completion\",\"created\":1763546727,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The sum of 2 and 3 is 5, and the product of 2 and 3 is 6.\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":246,\"completion_tokens\":25,\"total_tokens\":271,\"cost\":0.000792,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.000492,\"upstream_inference_completions_cost\":0.0003},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.828258792s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/multi_tool_streaming.yaml
new file mode 100644
index 000000000..83bd9cb9f
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/multi_tool_streaming.yaml
@@ -0,0 +1,81 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 894
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1763546729-jK1aeMuI8GK43IJd8TkJ","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546729,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"**Calculating Simultaneously**\n\nI'm structuring the code to run both operations, addition and multiplication, concurrently. I'm focusing on ensuring the `add` and `multiply` functions are called in parallel, as instructed. My next step will be to verify the parallel execution works as intended and then check the output.\n\n\n","reasoning_details":[{"type":"reasoning.text","text":"**Calculating Simultaneously**\n\nI'm structuring the code to run both operations, addition and multiplication, concurrently. I'm focusing on ensuring the `add` and `multiply` functions are called in parallel, as instructed. My next step will be to verify the parallel execution works as intended and then check the output.\n\n\n","format":"google-gemini-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1763546729-jK1aeMuI8GK43IJd8TkJ","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546729,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"reasoning":null,"reasoning_details":[{"id":"tool_add_UUaBEsZzO32E0mTPWBH0","type":"reasoning.encrypted","data":"CiQB4/H/XnAwaObJs/UHDkvpR2+9+jMNYdJYOEGoRvWFcj3rqWsKewHj8f9ec2BXB5/CHJY2tbAF2joRDykTYPX85xh1S7LSKBw/SpSri3Y8qUkQjdDpogRjUYFe4PWCuZXttjwMrQ7LbYZgLsbSWNnCo7ObETXAsb2PcGsPq2nR4sevZXoEA9ZWKZbFaxZ3r8ZOK9wV2MQm+WXbkaGZSMf2pAp4AePx/17Ii4UcjG/22OZT8kNkg2RI8OBuSDp9BHSmPswVuxRjJRWMi/HU9WGRnJi0vYixjChledG6apY+SzEwBqxDz+mHFY3MYGQmn4SUB379vKP8YdyiJdhgqjcB4Q6PtHJic06IMk5FCIueAvUP64Ij37RTTZufCooBAePx/17l/jZE4GbgvXhPqM3E3qtLqJ+WJ+cfTrmuXWyKKQVT4opjvNonxhs4Kwm0xudfVBIM6fFoPCclQx7+E4WD4+1eQqMHnU9mQWBMhfCRS4hliO9zZJrO3txN4uEF5JbaBXwHiX1yu4mvZ5OIkQWOM2xHqjY/TMq5qD+PSNQL0W26r9y8/Nhr","format":"google-gemini-v1","index":0}],"tool_calls":[{"index":0,"id":"tool_add_UUaBEsZzO32E0mTPWBH0","type":"function","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"}}]},"finish_reason":"tool_calls","native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1763546729-jK1aeMuI8GK43IJd8TkJ","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546729,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"reasoning":null,"reasoning_details":[],"tool_calls":[{"index":1,"id":"tool_multiply_qxw1ym6Mwm8U9MPesjJJ","type":"function","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"}}]},"finish_reason":"tool_calls","native_finish_reason":"STOP","logprobs":null}]}
+
+ data: {"id":"gen-1763546729-jK1aeMuI8GK43IJd8TkJ","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546729,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":57,"completion_tokens":83,"total_tokens":140,"cost":0.00111,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.000114,"upstream_inference_completions_cost":0.000996},"completion_tokens_details":{"reasoning_tokens":65,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 4.1319125s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2438
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"tool_add_UUaBEsZzO32E0mTPWBH0","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"tool_multiply_qxw1ym6Mwm8U9MPesjJJ","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"google-gemini-v1","index":0,"text":"**Calculating Simultaneously**\n\nI''m structuring the code to run both operations, addition and multiplication, concurrently. I''m focusing on ensuring the `add` and `multiply` functions are called in parallel, as instructed. My next step will be to verify the parallel execution works as intended and then check the output.\n\n\n","type":"reasoning.text"},{"data":"CiQB4/H/XnAwaObJs/UHDkvpR2+9+jMNYdJYOEGoRvWFcj3rqWsKewHj8f9ec2BXB5/CHJY2tbAF2joRDykTYPX85xh1S7LSKBw/SpSri3Y8qUkQjdDpogRjUYFe4PWCuZXttjwMrQ7LbYZgLsbSWNnCo7ObETXAsb2PcGsPq2nR4sevZXoEA9ZWKZbFaxZ3r8ZOK9wV2MQm+WXbkaGZSMf2pAp4AePx/17Ii4UcjG/22OZT8kNkg2RI8OBuSDp9BHSmPswVuxRjJRWMi/HU9WGRnJi0vYixjChledG6apY+SzEwBqxDz+mHFY3MYGQmn4SUB379vKP8YdyiJdhgqjcB4Q6PtHJic06IMk5FCIueAvUP64Ij37RTTZufCooBAePx/17l/jZE4GbgvXhPqM3E3qtLqJ+WJ+cfTrmuXWyKKQVT4opjvNonxhs4Kwm0xudfVBIM6fFoPCclQx7+E4WD4+1eQqMHnU9mQWBMhfCRS4hliO9zZJrO3txN4uEF5JbaBXwHiX1yu4mvZ5OIkQWOM2xHqjY/TMq5qD+PSNQL0W26r9y8/Nhr","format":"google-gemini-v1","id":"tool_add_UUaBEsZzO32E0mTPWBH0","index":0,"type":"reasoning.encrypted"}]},{"content":"5","tool_call_id":"tool_add_UUaBEsZzO32E0mTPWBH0","role":"tool"},{"content":"6","tool_call_id":"tool_multiply_qxw1ym6Mwm8U9MPesjJJ","role":"tool"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1763546733-tGHMAwoxWJIfDs5dnbLf","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546733,"choices":[{"index":0,"delta":{"role":"assistant","content":"The","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1763546733-tGHMAwoxWJIfDs5dnbLf","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546733,"choices":[{"index":0,"delta":{"role":"assistant","content":" result of adding 2 and 3 is 5, and the result of multiplying","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1763546733-tGHMAwoxWJIfDs5dnbLf","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546733,"choices":[{"index":0,"delta":{"role":"assistant","content":" them is 6.","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"STOP","logprobs":null}]}
+
+ data: {"id":"gen-1763546733-tGHMAwoxWJIfDs5dnbLf","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546733,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":108,"completion_tokens":23,"total_tokens":131,"cost":0.000492,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.000216,"upstream_inference_completions_cost":0.000276},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.800347541s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/simple.yaml
new file mode 100644
index 000000000..c7a954f6e
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 202
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1763546701-sBf8rH1mDRj14OloJK1h\",\"provider\":\"Google AI Studio\",\"model\":\"google/gemini-3-pro-preview\",\"object\":\"chat.completion\",\"created\":1763546701,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The most common way to say \\\"hi\\\" in Portuguese is:\\n\\n**Oi** (pronounced like *oy*)\\n\\nYou can also say **OlĆ”** (pronounced *oh-lah*), which is closer to \\\"hello.\\\"\",\"refusal\":null,\"reasoning\":\"**Pinpointing the Phrase**\\n\\nI've zeroed in on the user's need: a Portuguese \\\"hi.\\\" My analysis quickly identified the target language. Now, I'm working to compile the appropriate phrase for various social settings. \\\"Oi\\\" seems to be the informal winner, but I'm checking for more formal options to make the final answer complete.\\n\\n\\n**Refining the Greetings**\\n\\nI'm now zeroing in on the best ways to present the information. The original query was for \\\"hi\\\" but I realized that Portuguese doesn't always distinguish as directly as English. \\\"Oi\\\" is the clearest equivalent, and I've included \\\"OlĆ”\\\" as an alternative that is also common. I'm focusing on providing context with pronunciation for each word, and have decided to add a brief explanation to give the user even more helpful knowledge.\\n\\n\\n**Delivering the Greetings**\\n\\nI've determined that \\\"Oi\\\" is the most direct Portuguese translation of \\\"hi.\\\" Furthermore, I've incorporated the pronunciation key, noting \\\"Oi\\\" sounds like \\\"oy.\\\" For completeness, I've added \\\"OlĆ”\\\" to provide an alternative for the user, similar to \\\"hello.\\\"\\n\\n\\n\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"**Pinpointing the Phrase**\\n\\nI've zeroed in on the user's need: a Portuguese \\\"hi.\\\" My analysis quickly identified the target language. Now, I'm working to compile the appropriate phrase for various social settings. \\\"Oi\\\" seems to be the informal winner, but I'm checking for more formal options to make the final answer complete.\\n\\n\\n**Refining the Greetings**\\n\\nI'm now zeroing in on the best ways to present the information. The original query was for \\\"hi\\\" but I realized that Portuguese doesn't always distinguish as directly as English. \\\"Oi\\\" is the clearest equivalent, and I've included \\\"OlĆ”\\\" as an alternative that is also common. I'm focusing on providing context with pronunciation for each word, and have decided to add a brief explanation to give the user even more helpful knowledge.\\n\\n\\n**Delivering the Greetings**\\n\\nI've determined that \\\"Oi\\\" is the most direct Portuguese translation of \\\"hi.\\\" Furthermore, I've incorporated the pronunciation key, noting \\\"Oi\\\" sounds like \\\"oy.\\\" For completeness, I've added \\\"OlĆ”\\\" to provide an alternative for the user, similar to \\\"hello.\\\"\\n\\n\\n\",\"format\":\"google-gemini-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"EoIOCv8NAdHtim/suOdn1ujhrFG3R8JW2tDAAtgDNqX7cm0DqHCcE8txaRuUWah/MAsJ4rXLjh/w2fxpCu3fJHQDzn1ke7Zw6XkJiLtd0TdkVsylaDopnvZAvCYN91iFa2yUxxCaqc7UQYl0/ITgP8wIC4nrctK8PaHNtKSGfEg/vHibO+JstyKy1sKGMa5YVbyng+jUFezJAMqRIsCMYJ+Ga/HPeWUcUa/fKbUFSrHkGkXxbpNZRj2QaBy6u1MtOWtqwwBr+jdfKeewMoEczbg7XSeUduj60FVks3aVqEGZr18V9tg69CGEcjic0I8onA6AMnTUdzthEZastOZZByKbPM1F8VjeEwrGctcgFMK8NtXnp3npULV9XFCLW6/1wqe6xjl27NG3+YqBI/CS5C4rm5j1qJFVH+JWrJDOh1BlEeVP0NgRyih9lYVsDueCtZaIKU1Rj8meOjN0cc3M52ZGdFMIxEZzseHV/dMpF9pgVVlc5kI80banUxQRwQRWdX419Dlj+JQZ3sBihzdPtaXK5BK6KNUjcHZsKAAeXlrImePWSy4Cp9RX4/q7RRlUmU+n8REG6EC2agtSltotyOBN9RDKLja1ODmg4cE8T6O/FSfTpbpKUMJfuqFG84/EglfEAXueededzlskAkLibN/Kt9xNAUz6pNsUOVhGN/8ORdXUU6GzAxuupw2YA8+sbmx4kDvGS/iSM1M5rpUB7tWvDBLymiYqjbNUb+6GZmIchWD0hbd9P0hwPCcTX2tzGMENPHyJrvGadi4QlKoCnuZlNiqwy2TcFfgdR4y1js14DqEcWOMF5G62GFwAdLdivbvsUWiY1S37GPKbZzzdxMKYKby4qwqluvTLELlOa60/yr05xQ36nyWQB3NhRIFg9drRrsOw+276iVYzbHAfARThi8dDwA+W8TQZ2wkM/HIVkLjh55hRai6cGaFkiui820NhmPkLbpmLsYsV+DPpHU7sX/zJSXbZqvfKhSFv+zScDAo2EvUFpEIXbFdJ1U/sJ4G9BAEkwFdlXXdKxQ6xWO669x5nHjcu7RcC0tzRAuewrO5s6/qA6Q6w7eB6lniAiCp/rTssJRbnI5sNu4yLcx+GudUVBHt8fGoIGJCumzYDPllhq5G1rSpmAQ5FKiN9pVfEnezVxg6NAszWQyP2mN5p9svdWDcd59CxEfnisafxWwj2OIaIzrq5sTluJTnlzEMuaNmIV7O0GjmDHwgOzyM1xzJ4lhsfZ2O+ejwOIHD9QuThKxUWIWJQt2edSdwmbDXofqDzCt1/MT0q7xMaGjvLXIMXmgp9HdFPKmStHueys/JP0dCIc6cIYDXeqcxqQ6py+Zk2R5Mn8t8Kxz47a6ScxDw1YAlYgaMPqhTTnLVmd1Y0/m6EmKcWRiEp6N/wr3pvGLeDQvqY6LkFiWpz4VNjnkQySWYciQoOz/PTtTZqlRMbNzDt0s4aebxqKKApmWXaoCV6ouGz8nPt/zL6pbPrdz8zPyv/tm40YTnzkJhgUO34aOWdkpPeuWVLdz80Ey1s3MImUq2gSJ0BA9RFDfl/jSHmTfaQ75sgKevBJAikomBlDbW7RFAMVKccxLsCaS3jgrA+K8EtX2y4I0aEp9NU/o/hx3zO82SPhpb4MfTSbQElRNPZiTA4jwyRIxRLXs/MFWWS2LbE5WiPkTdzFgyWSwHkN1ykVBYFbSPGCApLZKjMzbSp8x2HgLrziAuObhPgKR2+Pa/rNIbKJfM8ytENpPx8x2UFIwI2ZDRUz9rFJ+maDDRkQ0pmcPZepA74wvdce6+gsRTtJPbjv8hhqE/l1IfcCIn8SdzASXaKuSknV18XnmTBaGAXIk8YN6no7O1xUAy/x5C7xhJBDtUZtpYHek1cW5VAJYUs5BqhDXaGWAxhw277ybNA21Gl5MVmaf4P163qCmvNuapISCFWfDEYTbNTImZkJtg5KExI641U7JBmJ8XJNItVfVxT69fcTCglW665lFqkV6cmfVSudA8XySr0sMm/pfOIXCnBODPXd6QBR7MjY7uJwynM+ZZoly1K640K+70TIU4iTRIvP9hQ2m3R+F1kTdRGOLwqvfhyj2E24JgFcS6ZuVnan8llQp56jxHAchAX9VEl60RQmOzcECzOynKCZaZA3YH+72pYxDhu5WrK/mG4BmL3miYMsofIkXi/ZvYsMC3XjL+hYiL1tttt8E0eCWY73Wd2437jkM/4vMTrrJO99rqr4ERktB/FvChaiSFHHjPFQL3LAXgd0knyCqWC4yh6EPEYQuUfLI2YuGrIrpGjtecHBTvvcU/c2lVMWBvA2M/E4lX8dhKvv+5WcpfE1ZQ33f6mdLGbiWR8Z9jK2o8To/5cVAiD0jVmJ1aR2ZC9WH/oLw9+kbMSiamT\",\"format\":\"google-gemini-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":11,\"completion_tokens\":460,\"total_tokens\":471,\"cost\":0.005542,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.000022,\"upstream_inference_completions_cost\":0.00552},\"completion_tokens_details\":{\"reasoning_tokens\":414,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.918398667s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/simple_streaming.yaml
new file mode 100644
index 000000000..bca71ad4d
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/simple_streaming.yaml
@@ -0,0 +1,44 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 256
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"stream_options":{"include_usage":true},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1763546708-WlSEiEPr7nn7Uso3yUg7","provider":"Google AI Studio","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546708,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"**Considering the Greeting**\n\nI've narrowed it down to the essentials: \"Oi\" is the go-to informal greeting in Portuguese, and it's perfect for a casual \"hi.\" No need to overcomplicate things!\n\n\n","reasoning_details":[{"type":"reasoning.text","text":"**Considering the Greeting**\n\nI've narrowed it down to the essentials: \"Oi\" is the go-to informal greeting in Portuguese, and it's perfect for a casual \"hi.\" No need to overcomplicate things!\n\n\n","format":"google-gemini-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1763546708-WlSEiEPr7nn7Uso3yUg7","provider":"Google AI Studio","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546708,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"**Refining the Response**\n\nI've decided to include both options: \"Oi\" for \"Hi\" and \"OlĆ”\" for \"Hello.\" I've considered that context is key, but providing both will give a richer response, especially for learners. I've also verified the pronunciation for clarity.\n\n\n","reasoning_details":[{"type":"reasoning.text","text":"**Refining the Response**\n\nI've decided to include both options: \"Oi\" for \"Hi\" and \"OlĆ”\" for \"Hello.\" I've considered that context is key, but providing both will give a richer response, especially for learners. I've also verified the pronunciation for clarity.\n\n\n","format":"google-gemini-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1763546708-WlSEiEPr7nn7Uso3yUg7","provider":"Google AI Studio","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546708,"choices":[{"index":0,"delta":{"role":"assistant","content":"**Oi**\n\nYou can also say **OlĆ”** (which is more like \"Hello\").","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1763546708-WlSEiEPr7nn7Uso3yUg7","provider":"Google AI Studio","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546708,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.encrypted","data":"ErwJCrkJAdHtim8y6vZPaBmPFxd5WcUQDT37XvDgtHy40D9ssC7Q5sBYDgvpMpDHsKIr9sAd+1fDRUXMgbG7K2vqZu985V9uTI35JWXsj5xAuwToyGe1vRObteKgBxXeORFcBFPL5banYDBJTZ61ggeQGsw67asE5pJMGcxTprujlpCJlvbGoJ9FNJATG2qHMW6XouPgkDLmlwodUjGM2DrV5tBKqJX6DhlA1Ofc/+GdlPtxOeQFsgLBpjFH5E+gvqwpJT5UrC6niF+hcRZGzLADjiJwlNUsYswb60CuVwpXFZ3gf+Zt9d/AzyC8o3xXD9m9haNB1uy+/67YtmB6768175bV/r579EQyQLQVrOANQPP9zQTDqxGM35+zmF17ITgpLzy7wwzGjjEvqsE4qGcfbPV8wGPreIuUa4Ur3unuVxthjrCw53FOpwljSJyep/qH2ibynSYj/dqtsWADwlkJaHaWGJviMTPZnGtuk1HEQkbrZJR1V6+A9eu67DKfCvsmymy0ZAxFQ9doD9gDBsXuGcUQWeG16k3kKzU70CFJEFO3SMtH1g5+yK6kV+zlmdbZRH6Ci32cMBSCUjGKRkyfkHEXQQ1u3Xlxgch3ZVn+0DeER2hCE5JE1PG8dUUs0IuLDvm2ogPCzHyIW3MT/bpamjBrOnlvXmvOVCJxiRHFNX8e/R0ymn/sz1sa8OaI+dJ7MZWUuBWdpQky1Wx9UrqMgMSFeo3PB8BDOp33RHQ4t2Ttx8nnmVt8UvHlizzQm3Xhcm7osn4G+MORhhr2l70sJgTE+Ha1I5e4H2Ul6r084IPcfzfk/QJsg2a8leLudrrq4bi0eNhGhSFvnVgMckXoaAZrE/qIILsJW+TOuvd64/+322HiFg7AWzyrGkfo2Jam1CJRIPBGvjhoLe8NA0vBzD2159i1Bn1rWCgBsk06+usdl59K9Z3Eb/WsZ+TPM5UWNoIBGfvyDNIF6M7iun7dtECLcAMim9f2Gs5sp++MBzWITxrGy2IuIjGinmNCgSbJ0Y6tQi/vgo4LGWOJb0MwAG6jc4/0GdaT7dYz7tiHPyTSB9J2qQAgFbV2E7TVpLs4aVC71Kn+4KXULEt4DPR5XKAb66/y9QZciFGYU0cExkgbGZK5Yabpva/xYln/sEW2mLKVy6xDMrKxPcIBnAHumFL3BBkl1cwCSU2JjgeW47yLvId5oPn/odD98zjOrnE1tn9iUlP5zdmNqVEBE5DRw4GQ+BESrkhlI29cxRvpIR1E9ne2IntlYXYXZ3gltf4lf9CCeSHG3nDi0lmPTX7ucaR4zjLhvF/Stl/KjAEAcQGx+9kPCSYQgRyvXDEJasZB2Jeq0zwRVFuUaU8ZvMtiBE9qSZbAVOt4CgvZlUv88howGleHmoLQGFW9A505/cSoIRRct89KJaC0ZuUj88cEW1BAIKpZyZvARmmzjo2WegHqIMGPlpX71kRr7mecgW5rA2WQMRmfDw8IdSLcM1INhoexL7fc0zxMGuZjZZt/Wp19rACsI6XphlNi+LMh6dfqsAcjalxST7YYHk0kWn6PJ2Qqeexnes/3cuf9GRFJgJUx0OOqFmLFCSJVXwW4F4cIdrclVY6bk0bzp+fg","format":"google-gemini-v1","index":0}]},"finish_reason":"stop","native_finish_reason":"STOP","logprobs":null}]}
+
+ data: {"id":"gen-1763546708-WlSEiEPr7nn7Uso3yUg7","provider":"Google AI Studio","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546708,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":11,"completion_tokens":281,"total_tokens":292,"cost":0.003394,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.000022,"upstream_inference_completions_cost":0.003372},"completion_tokens_details":{"reasoning_tokens":262,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.670654208s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/tool.yaml
new file mode 100644
index 000000000..81bfd4c5f
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 494
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1763546712-oowOHbRdTatTsgOviYVp\",\"provider\":\"Google AI Studio\",\"model\":\"google/gemini-3-pro-preview\",\"object\":\"chat.completion\",\"created\":1763546712,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":\"**Investigating Weather Retrieval**\\n\\nI'm currently focused on the user's request for weather in Florence, Italy. My primary action is to evaluate available tools. The `get_weather` function looks promising, especially since it accepts a `location` parameter. I intend to use this function to provide the user with the information they need. I'm getting ready to use it!\\n\\n\\n**Evaluating Function Application**\\n\\nI've now attempted to apply the `get_weather` function with the specified location: 'Florence, Italy'. I'm expecting this will successfully retrieve the weather data the user is seeking. The next step is to process and present the received data.\\n\\n\\n\",\"tool_calls\":[{\"index\":0,\"id\":\"tool_weather_j0DpU01anCLITtFWepce\",\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"**Investigating Weather Retrieval**\\n\\nI'm currently focused on the user's request for weather in Florence, Italy. My primary action is to evaluate available tools. The `get_weather` function looks promising, especially since it accepts a `location` parameter. I intend to use this function to provide the user with the information they need. I'm getting ready to use it!\\n\\n\\n**Evaluating Function Application**\\n\\nI've now attempted to apply the `get_weather` function with the specified location: 'Florence, Italy'. I'm expecting this will successfully retrieve the weather data the user is seeking. The next step is to process and present the received data.\\n\\n\\n\",\"format\":\"google-gemini-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"EtgDCtUDAdHtim+owmT73Js7vjC7xHBLN2/s4c4jI3o7DgAlJut+e/0MVHbwVhm4Qs1QoUNwVqV2Ny2m7j7qWTwqjuSqma19OdaHD1U2PRkvsPLUV7H8J9XcFMsRZne3U9IEo6RnHXZk0ynhb9EEsdGPwzMD1vu3CNPyPsvbBapGQ5c+G9q0xD0mh7A43k8I4o4uHlHUftH+TGDdEk3veSoUhy3zRESdf1LEJowbsRakH7iaVgfyL44HjKBAkh3elryR1j+FZCDpoI13LofJ5fPUCp3GbzWgitkPHrdYIH0rjsYjJlZF2INPrbDiUd/qpTHY2xi3HwhM0UiYG/QB8vxkQ1oEC2LgRMsMB7dQaG9On3Ww+4n54vEoLdPoNaLi+ZKJlHEf4ukiEufyDPDG063qrXqrq1+rneO0W2Yk4uCH9cYzjTJYk5YurWLEX9vZaHucY0hIfzrhlh32d5JDGvwa6gue5bjase1MSPngiyEAQmTOI8Aw30jozWBlI36VyyKjLoo24tC181vOvLjCmwZX7DDFaxIGVlQzWNAnJm1StcpKrhFuqV/FocTe6hlYuTg9F5UqyVXGmfTTquXHE8jqhOybQ4+G7zKjHaEgXDc23ou19YenEtBx0g==\",\"id\":\"tool_weather_j0DpU01anCLITtFWepce\",\"format\":\"google-gemini-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":65,\"completion_tokens\":100,\"total_tokens\":165,\"cost\":0.00133,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00013,\"upstream_inference_completions_cost\":0.0012},\"completion_tokens_details\":{\"reasoning_tokens\":84,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.57858475s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2274
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"tool_weather_j0DpU01anCLITtFWepce","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"google-gemini-v1","index":0,"text":"**Investigating Weather Retrieval**\n\nI''m currently focused on the user''s request for weather in Florence, Italy. My primary action is to evaluate available tools. The `get_weather` function looks promising, especially since it accepts a `location` parameter. I intend to use this function to provide the user with the information they need. I''m getting ready to use it!\n\n\n**Evaluating Function Application**\n\nI''ve now attempted to apply the `get_weather` function with the specified location: ''Florence, Italy''. I''m expecting this will successfully retrieve the weather data the user is seeking. The next step is to process and present the received data.\n\n\n","type":"reasoning.text"},{"data":"EtgDCtUDAdHtim+owmT73Js7vjC7xHBLN2/s4c4jI3o7DgAlJut+e/0MVHbwVhm4Qs1QoUNwVqV2Ny2m7j7qWTwqjuSqma19OdaHD1U2PRkvsPLUV7H8J9XcFMsRZne3U9IEo6RnHXZk0ynhb9EEsdGPwzMD1vu3CNPyPsvbBapGQ5c+G9q0xD0mh7A43k8I4o4uHlHUftH+TGDdEk3veSoUhy3zRESdf1LEJowbsRakH7iaVgfyL44HjKBAkh3elryR1j+FZCDpoI13LofJ5fPUCp3GbzWgitkPHrdYIH0rjsYjJlZF2INPrbDiUd/qpTHY2xi3HwhM0UiYG/QB8vxkQ1oEC2LgRMsMB7dQaG9On3Ww+4n54vEoLdPoNaLi+ZKJlHEf4ukiEufyDPDG063qrXqrq1+rneO0W2Yk4uCH9cYzjTJYk5YurWLEX9vZaHucY0hIfzrhlh32d5JDGvwa6gue5bjase1MSPngiyEAQmTOI8Aw30jozWBlI36VyyKjLoo24tC181vOvLjCmwZX7DDFaxIGVlQzWNAnJm1StcpKrhFuqV/FocTe6hlYuTg9F5UqyVXGmfTTquXHE8jqhOybQ4+G7zKjHaEgXDc23ou19YenEtBx0g==","format":"google-gemini-v1","id":"tool_weather_j0DpU01anCLITtFWepce","index":0,"type":"reasoning.encrypted"}]},{"content":"40 C","tool_call_id":"tool_weather_j0DpU01anCLITtFWepce","role":"tool"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1763546715-2isSMEAOtYZrJ9E3lrvA\",\"provider\":\"Google AI Studio\",\"model\":\"google/gemini-3-pro-preview\",\"object\":\"chat.completion\",\"created\":1763546715,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The weather in Florence, Italy is currently 40 degrees Celsius.\",\"refusal\":null,\"reasoning\":\"**Deliver the Answer**\\n\\nI've got the weather data for Florence - it's a scorching 40 degrees Celsius. Now, I'm crafting the response to the user, ensuring the temperature is clearly stated.\\n\\n\\n\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"**Deliver the Answer**\\n\\nI've got the weather data for Florence - it's a scorching 40 degrees Celsius. Now, I'm crafting the response to the user, ensuring the temperature is clearly stated.\\n\\n\\n\",\"format\":\"google-gemini-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"Eo4CCosCAdHtim/M+Wv8vjHlzGm/0BnHiNkdjJezGKNj1AC7oH5ExVuvQNPnY51uym511/C6HVjzEeN5C286hYJXgQf6G4uTuoo5azntFo9nK7wER9jf98Amtt/3A6KpQpLzVDwe3Lidp5nHgdUzpIws5IwliAX9VtD6ktPhiI8v4UkFXsRp4sv2bI4Zvf4ORogdHJDN2fcLCTnZXOSVEdw6sZ4OZNI+JGc4tUyCE5cuU0jFWq0R/2eS6qn5N9TkBIx61H+OeXFyZtxX5edxtAykhSHv+kDa81s+wiYuwneBrb0uknwmuqHR3TTxzcn813ELwMnOaORVujw47blm2urGBxS9q7xj62udCT0wMli8\",\"format\":\"google-gemini-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":193,\"completion_tokens\":55,\"total_tokens\":248,\"cost\":0.001046,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.000386,\"upstream_inference_completions_cost\":0.00066},\"completion_tokens_details\":{\"reasoning_tokens\":41,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.627752916s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/tool_streaming.yaml
new file mode 100644
index 000000000..4a017b561
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gemini-3-pro-preview/tool_streaming.yaml
@@ -0,0 +1,81 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 548
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1763546718-VolgJ4S2Tix4gqNJ9Pn9","provider":"Google AI Studio","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546718,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"**Pinpointing the Weather**\n\nI've homed in on using the `weather` tool ā a perfect match for the user's request! Now, I'm focusing on obtaining the necessary `location` parameter to make it work. I need to figure out how to parse \"Florence, Italy\" into a format the tool understands. I will need to get a location from a query using an available tool.\n\n\n","reasoning_details":[{"type":"reasoning.text","text":"**Pinpointing the Weather**\n\nI've homed in on using the `weather` tool ā a perfect match for the user's request! Now, I'm focusing on obtaining the necessary `location` parameter to make it work. I need to figure out how to parse \"Florence, Italy\" into a format the tool understands. I will need to get a location from a query using an available tool.\n\n\n","format":"google-gemini-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1763546718-VolgJ4S2Tix4gqNJ9Pn9","provider":"Google AI Studio","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546718,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"**Deciphering the Location**\n\nI've determined that the user's input directly provides the `location` needed by the weather tool. Specifically, \"Florence, Italy\" can be directly used as the `location` parameter. Thus, I'll execute the `weather` tool with `location='Florence, Italy'` as the argument.\n\n\n","reasoning_details":[{"type":"reasoning.text","text":"**Deciphering the Location**\n\nI've determined that the user's input directly provides the `location` needed by the weather tool. Specifically, \"Florence, Italy\" can be directly used as the `location` parameter. Thus, I'll execute the `weather` tool with `location='Florence, Italy'` as the argument.\n\n\n","format":"google-gemini-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1763546718-VolgJ4S2Tix4gqNJ9Pn9","provider":"Google AI Studio","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546718,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"reasoning":null,"reasoning_details":[{"id":"tool_weather_ZdFohc8uRXpsZsX3K74b","type":"reasoning.encrypted","data":"EvUDCvIDAdHtim/YGUj5NcE2xF6SC6IYQg3S9nvktXv6CQcy76ZTZdJ+5dFMIlPCXqVXLIrccmk3PX5MWiEM0NB0t4Cie2azaqDdgGgAN2kCKpZuJRIbqFDLWNR+oa0r2D7ShyyrWyAbz6YTjgBHvj8KqduwdA3Ya/9BKE1cuuacK4Sq3kH+cKpLMPXA3m4cZ7s/n02lvHHn2koGbXppEj7BuYxwHdDXOhHKN0JggJ9xzHR1DjL81e3DB3I7FITdUSL5U/DRfTwAErqfuTXfYUlNB2X3YUYHZ1vU0uCSCeliiG/mzmotfHHhb7VuzGmgLquhkQGcHbwoOkqTFVbT7iNBFg6kPtNc5qukvyprufaT3FfEupXH1qBv0djPYLwGyPsTIwDYt4QVsDd7pNb4yDj/1MrO/acvaCfz2vhwglSnTC0GUndMwFYCV991EAcsnLbPWNZcuztCzt8tvMjgUJkSQrRGuXUFUre6JQzv4VHl54NxxpTP/pOaWdKldT/j8Y64sb1tQwXYq1qFdYgKzh+U0ig/l05ZIvq9Mzw+R8p4qoug9wGV1U1cvXDwCIrkhN+k/j7DzcAg6kRgpNM26bUpBWZ7t8jhFgUIv+HyXfrBN9V4Q0Jd2ifN4yW68JBhCNeTe3d+/OokV5V8Y1McC5Moi3HC1Roq","format":"google-gemini-v1","index":0}],"tool_calls":[{"index":0,"id":"tool_weather_ZdFohc8uRXpsZsX3K74b","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence, Italy\"}"}}]},"finish_reason":"tool_calls","native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1763546718-VolgJ4S2Tix4gqNJ9Pn9","provider":"Google AI Studio","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546718,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"STOP","logprobs":null}]}
+
+ data: {"id":"gen-1763546718-VolgJ4S2Tix4gqNJ9Pn9","provider":"Google AI Studio","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546718,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":65,"completion_tokens":104,"total_tokens":169,"cost":0.001378,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00013,"upstream_inference_completions_cost":0.001248},"completion_tokens_details":{"reasoning_tokens":88,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 3.000569167s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2368
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"tool_weather_ZdFohc8uRXpsZsX3K74b","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"google-gemini-v1","index":0,"text":"**Pinpointing the Weather**\n\nI''ve homed in on using the `weather` tool ā a perfect match for the user''s request! Now, I''m focusing on obtaining the necessary `location` parameter to make it work. I need to figure out how to parse \"Florence, Italy\" into a format the tool understands. I will need to get a location from a query using an available tool.\n\n\n**Deciphering the Location**\n\nI''ve determined that the user''s input directly provides the `location` needed by the weather tool. Specifically, \"Florence, Italy\" can be directly used as the `location` parameter. Thus, I''ll execute the `weather` tool with `location=''Florence, Italy''` as the argument.\n\n\n","type":"reasoning.text"},{"data":"EvUDCvIDAdHtim/YGUj5NcE2xF6SC6IYQg3S9nvktXv6CQcy76ZTZdJ+5dFMIlPCXqVXLIrccmk3PX5MWiEM0NB0t4Cie2azaqDdgGgAN2kCKpZuJRIbqFDLWNR+oa0r2D7ShyyrWyAbz6YTjgBHvj8KqduwdA3Ya/9BKE1cuuacK4Sq3kH+cKpLMPXA3m4cZ7s/n02lvHHn2koGbXppEj7BuYxwHdDXOhHKN0JggJ9xzHR1DjL81e3DB3I7FITdUSL5U/DRfTwAErqfuTXfYUlNB2X3YUYHZ1vU0uCSCeliiG/mzmotfHHhb7VuzGmgLquhkQGcHbwoOkqTFVbT7iNBFg6kPtNc5qukvyprufaT3FfEupXH1qBv0djPYLwGyPsTIwDYt4QVsDd7pNb4yDj/1MrO/acvaCfz2vhwglSnTC0GUndMwFYCV991EAcsnLbPWNZcuztCzt8tvMjgUJkSQrRGuXUFUre6JQzv4VHl54NxxpTP/pOaWdKldT/j8Y64sb1tQwXYq1qFdYgKzh+U0ig/l05ZIvq9Mzw+R8p4qoug9wGV1U1cvXDwCIrkhN+k/j7DzcAg6kRgpNM26bUpBWZ7t8jhFgUIv+HyXfrBN9V4Q0Jd2ifN4yW68JBhCNeTe3d+/OokV5V8Y1McC5Moi3HC1Roq","format":"google-gemini-v1","id":"tool_weather_ZdFohc8uRXpsZsX3K74b","index":0,"type":"reasoning.encrypted"}]},{"content":"40 C","tool_call_id":"tool_weather_ZdFohc8uRXpsZsX3K74b","role":"tool"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1763546721-kbEZ3lLMWQc3gbgqRMRp","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546721,"choices":[{"index":0,"delta":{"role":"assistant","content":"The weather in Florence","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1763546721-kbEZ3lLMWQc3gbgqRMRp","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546721,"choices":[{"index":0,"delta":{"role":"assistant","content":", Italy is 40°C.","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"STOP","logprobs":null}]}
+
+ data: {"id":"gen-1763546721-kbEZ3lLMWQc3gbgqRMRp","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546721,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":56,"completion_tokens":13,"total_tokens":69,"cost":0.000268,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.000112,"upstream_inference_completions_cost":0.000156},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.668490333s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/multi_tool.yaml
new file mode 100644
index 000000000..6f923c22c
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 842
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"z-ai/glm-4.5","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054179-qLoGjMjTQwOC2zpt8yLb\",\"provider\":\"Z.AI\",\"model\":\"z-ai/glm-4.5\",\"object\":\"chat.completion\",\"created\":1761054179,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\\nI'll both add and multiply the numbers 2 and 3 for you.\\n\",\"refusal\":null,\"reasoning\":\"\\nThe user is asking me to both add and multiply the numbers 2 and 3. I need to use both the add and multiply functions as requested. Let me call both functions with the parameters a=2 and b=3.\",\"tool_calls\":[{\"id\":\"call_37172aa3ef2a4e3d896c64a3\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"add\",\"arguments\":\"{\\\"a\\\":2,\\\"b\\\":3}\"}},{\"id\":\"call_d6b73be9f6344636b4c5b9ca\",\"index\":1,\"type\":\"function\",\"function\":{\"name\":\"multiply\",\"arguments\":\"{\\\"a\\\":2,\\\"b\\\":3}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"\\nThe user is asking me to both add and multiply the numbers 2 and 3. I need to use both the add and multiply functions as requested. Let me call both functions with the parameters a=2 and b=3.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":286,\"completion_tokens\":109,\"total_tokens\":395,\"cost\":0.00027175,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":285,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00003195,\"upstream_inference_completions_cost\":0.0002398},\"completion_tokens_details\":{\"reasoning_tokens\":49,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 779.738958ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1619
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"\nI''ll both add and multiply the numbers 2 and 3 for you.\n","tool_calls":[{"id":"call_37172aa3ef2a4e3d896c64a3","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"call_d6b73be9f6344636b4c5b9ca","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"unknown","index":0,"text":"\nThe user is asking me to both add and multiply the numbers 2 and 3. I need to use both the add and multiply functions as requested. Let me call both functions with the parameters a=2 and b=3.","type":"reasoning.text"}]},{"content":"5","tool_call_id":"call_37172aa3ef2a4e3d896c64a3","role":"tool"},{"content":"6","tool_call_id":"call_d6b73be9f6344636b4c5b9ca","role":"tool"}],"model":"z-ai/glm-4.5","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054183-s23tnwwmDM6FLYUTCiTH\",\"provider\":\"Z.AI\",\"model\":\"z-ai/glm-4.5\",\"object\":\"chat.completion\",\"created\":1761054183,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\\nThe results for adding and multiplying 2 and 3 are:\\n\\n- **Addition**: 2 + 3 = 5\\n- **Multiplication**: 2 Ć 3 = 6\",\"refusal\":null,\"reasoning\":\"\\nThe user asked me to add and multiply the numbers 2 and 3. I used both functions as requested:\\n- Add: 2 + 3 = 5\\n- Multiply: 2 Ć 3 = 6\\n\\nI should present both results clearly to the user.\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"\\nThe user asked me to add and multiply the numbers 2 and 3. I used both functions as requested:\\n- Add: 2 + 3 = 5\\n- Multiply: 2 Ć 3 = 6\\n\\nI should present both results clearly to the user.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":361,\"completion_tokens\":102,\"total_tokens\":463,\"cost\":0.00041993,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":43,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00019553,\"upstream_inference_completions_cost\":0.0002244},\"completion_tokens_details\":{\"reasoning_tokens\":51,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 603.16025ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/multi_tool_streaming.yaml
new file mode 100644
index 000000000..f7cd1c9d8
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/multi_tool_streaming.yaml
@@ -0,0 +1,415 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 879
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"z-ai/glm-4.5","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\n","reasoning_details":[{"type":"reasoning.text","text":"\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"The","reasoning_details":[{"type":"reasoning.text","text":"The","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.text","text":" user","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" wants","reasoning_details":[{"type":"reasoning.text","text":" wants","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" me","reasoning_details":[{"type":"reasoning.text","text":" me","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.text","text":" to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" both","reasoning_details":[{"type":"reasoning.text","text":" both","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" add","reasoning_details":[{"type":"reasoning.text","text":" add","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.text","text":" and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" multiply","reasoning_details":[{"type":"reasoning.text","text":" multiply","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" numbers","reasoning_details":[{"type":"reasoning.text","text":" numbers","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.text","text":" ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"2","reasoning_details":[{"type":"reasoning.text","text":"2","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.text","text":" and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.text","text":" ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"3","reasoning_details":[{"type":"reasoning.text","text":"3","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.text","text":" I","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" need","reasoning_details":[{"type":"reasoning.text","text":" need","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.text","text":" to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" use","reasoning_details":[{"type":"reasoning.text","text":" use","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" both","reasoning_details":[{"type":"reasoning.text","text":" both","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" add","reasoning_details":[{"type":"reasoning.text","text":" add","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.text","text":" and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" multiply","reasoning_details":[{"type":"reasoning.text","text":" multiply","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" functions","reasoning_details":[{"type":"reasoning.text","text":" functions","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" with","reasoning_details":[{"type":"reasoning.text","text":" with","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" same","reasoning_details":[{"type":"reasoning.text","text":" same","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" parameters","reasoning_details":[{"type":"reasoning.text","text":" parameters","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".\n\n","reasoning_details":[{"type":"reasoning.text","text":".\n\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"For","reasoning_details":[{"type":"reasoning.text","text":"For","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" add","reasoning_details":[{"type":"reasoning.text","text":" add","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":":","reasoning_details":[{"type":"reasoning.text","text":":","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.text","text":" a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"=","reasoning_details":[{"type":"reasoning.text","text":"=","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"2","reasoning_details":[{"type":"reasoning.text","text":"2","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.text","text":",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" b","reasoning_details":[{"type":"reasoning.text","text":" b","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"=","reasoning_details":[{"type":"reasoning.text","text":"=","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"3","reasoning_details":[{"type":"reasoning.text","text":"3","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\n","reasoning_details":[{"type":"reasoning.text","text":"\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"For","reasoning_details":[{"type":"reasoning.text","text":"For","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" multiply","reasoning_details":[{"type":"reasoning.text","text":" multiply","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":":","reasoning_details":[{"type":"reasoning.text","text":":","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.text","text":" a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"=","reasoning_details":[{"type":"reasoning.text","text":"=","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"2","reasoning_details":[{"type":"reasoning.text","text":"2","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.text","text":",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" b","reasoning_details":[{"type":"reasoning.text","text":" b","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"=","reasoning_details":[{"type":"reasoning.text","text":"=","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"3","reasoning_details":[{"type":"reasoning.text","text":"3","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\n\n","reasoning_details":[{"type":"reasoning.text","text":"\n\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"I","reasoning_details":[{"type":"reasoning.text","text":"I","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"'ll","reasoning_details":[{"type":"reasoning.text","text":"'ll","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" call","reasoning_details":[{"type":"reasoning.text","text":" call","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" both","reasoning_details":[{"type":"reasoning.text","text":" both","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" functions","reasoning_details":[{"type":"reasoning.text","text":" functions","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"I","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"'ll","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":" add","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":" and","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":" multiply","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":" the","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":" numbers","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"2","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":" and","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"3","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":" for","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":" you","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":".\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"call_e4bee396c93d4f45be357034","index":0,"type":"function","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"call_9ece1ae129a14ac2875f398f","index":1,"type":"function","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}]}
+
+ data: {"id":"gen-1761054186-i7sVLSLSYe9xbfqthPh4","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054186,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":282,"completion_tokens":121,"total_tokens":403,"cost":0.00029771,"is_byok":false,"prompt_tokens_details":{"cached_tokens":281,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00003151,"upstream_inference_completions_cost":0.0002662},"completion_tokens_details":{"reasoning_tokens":57,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 507.268375ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1671
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"\nI''ll add and multiply the numbers 2 and 3 for you.\n","tool_calls":[{"id":"call_e4bee396c93d4f45be357034","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"call_9ece1ae129a14ac2875f398f","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"unknown","index":0,"text":"The user wants me to both add and multiply the numbers 2 and 3. I need to use both the add and multiply functions with the same parameters.\n\nFor add: a=2, b=3\nFor multiply: a=2, b=3\n\nI''ll call both functions.","type":"reasoning.text"}]},{"content":"5","tool_call_id":"call_e4bee396c93d4f45be357034","role":"tool"},{"content":"6","tool_call_id":"call_9ece1ae129a14ac2875f398f","role":"tool"}],"model":"z-ai/glm-4.5","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\n","reasoning_details":[{"type":"reasoning.text","text":"\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"The","reasoning_details":[{"type":"reasoning.text","text":"The","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.text","text":" user","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" asked","reasoning_details":[{"type":"reasoning.text","text":" asked","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" me","reasoning_details":[{"type":"reasoning.text","text":" me","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.text","text":" to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" add","reasoning_details":[{"type":"reasoning.text","text":" add","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.text","text":" and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" multiply","reasoning_details":[{"type":"reasoning.text","text":" multiply","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" numbers","reasoning_details":[{"type":"reasoning.text","text":" numbers","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.text","text":" ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"2","reasoning_details":[{"type":"reasoning.text","text":"2","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.text","text":" and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.text","text":" ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"3","reasoning_details":[{"type":"reasoning.text","text":"3","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.text","text":" I","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" used","reasoning_details":[{"type":"reasoning.text","text":" used","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" both","reasoning_details":[{"type":"reasoning.text","text":" both","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" add","reasoning_details":[{"type":"reasoning.text","text":" add","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.text","text":" and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" multiply","reasoning_details":[{"type":"reasoning.text","text":" multiply","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" functions","reasoning_details":[{"type":"reasoning.text","text":" functions","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" as","reasoning_details":[{"type":"reasoning.text","text":" as","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" requested","reasoning_details":[{"type":"reasoning.text","text":" requested","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" The","reasoning_details":[{"type":"reasoning.text","text":" The","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" results","reasoning_details":[{"type":"reasoning.text","text":" results","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" are","reasoning_details":[{"type":"reasoning.text","text":" are","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":":\n","reasoning_details":[{"type":"reasoning.text","text":":\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"-","reasoning_details":[{"type":"reasoning.text","text":"-","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Adding","reasoning_details":[{"type":"reasoning.text","text":" Adding","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.text","text":" ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"2","reasoning_details":[{"type":"reasoning.text","text":"2","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.text","text":" and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.text","text":" ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"3","reasoning_details":[{"type":"reasoning.text","text":"3","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" gives","reasoning_details":[{"type":"reasoning.text","text":" gives","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.text","text":" ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"5","reasoning_details":[{"type":"reasoning.text","text":"5","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\n","reasoning_details":[{"type":"reasoning.text","text":"\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"-","reasoning_details":[{"type":"reasoning.text","text":"-","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Multip","reasoning_details":[{"type":"reasoning.text","text":" Multip","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"lying","reasoning_details":[{"type":"reasoning.text","text":"lying","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.text","text":" ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"2","reasoning_details":[{"type":"reasoning.text","text":"2","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.text","text":" and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.text","text":" ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"3","reasoning_details":[{"type":"reasoning.text","text":"3","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" gives","reasoning_details":[{"type":"reasoning.text","text":" gives","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.text","text":" ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"6","reasoning_details":[{"type":"reasoning.text","text":"6","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\n\n","reasoning_details":[{"type":"reasoning.text","text":"\n\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"I","reasoning_details":[{"type":"reasoning.text","text":"I","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" should","reasoning_details":[{"type":"reasoning.text","text":" should","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" present","reasoning_details":[{"type":"reasoning.text","text":" present","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" both","reasoning_details":[{"type":"reasoning.text","text":" both","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" results","reasoning_details":[{"type":"reasoning.text","text":" results","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" clearly","reasoning_details":[{"type":"reasoning.text","text":" clearly","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.text","text":" to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.text","text":" user","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"The","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":" results","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":" are","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":":\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"-","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":" Adding","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"2","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":" and","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"3","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":":","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"5","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"-","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":" Multip","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"lying","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"2","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":" and","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"3","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":":","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"6","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1761054190-jWjwHKksdC9C7cTM6ypS","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054190,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":356,"completion_tokens":95,"total_tokens":451,"cost":0.00024865,"is_byok":false,"prompt_tokens_details":{"cached_tokens":355,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00003965,"upstream_inference_completions_cost":0.000209},"completion_tokens_details":{"reasoning_tokens":64,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 705.411167ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/simple.yaml
new file mode 100644
index 000000000..41c62999c
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 187
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"z-ai/glm-4.5","max_tokens":4000,"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054159-WMu3LlZsFNnSnGGMLRdI\",\"provider\":\"Z.AI\",\"model\":\"z-ai/glm-4.5\",\"object\":\"chat.completion\",\"created\":1761054159,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"In Portuguese, you can say \\\"hi\\\" as:\\n\\n\\\"Oi!\\\" (informal, commonly used among friends and in casual situations)\\n\\nor \\n\\n\\\"OlĆ”!\\\" (more formal, but still commonly used in various contexts)\\n\\nBoth are common greetings in Portuguese-speaking countries like Brazil and Portugal.\",\"refusal\":null,\"reasoning\":\"\\nThe user is asking me to say \\\"hi\\\" in Portuguese. I'll provide the translation and maybe a brief explanation.\\n\\nIn Portuguese, \\\"hi\\\" is typically translated as \\\"oi\\\" (informal) or \\\"olĆ”\\\" (more formal). Both are common greetings in Portuguese.\\n\\nI'll provide both options with a brief explanation of when each might be used.\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"\\nThe user is asking me to say \\\"hi\\\" in Portuguese. I'll provide the translation and maybe a brief explanation.\\n\\nIn Portuguese, \\\"hi\\\" is typically translated as \\\"oi\\\" (informal) or \\\"olĆ”\\\" (more formal). Both are common greetings in Portuguese.\\n\\nI'll provide both options with a brief explanation of when each might be used.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":16,\"completion_tokens\":135,\"total_tokens\":151,\"cost\":0.00030317,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":7,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00000617,\"upstream_inference_completions_cost\":0.000297},\"completion_tokens_details\":{\"reasoning_tokens\":84,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 577.011208ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/simple_streaming.yaml
new file mode 100644
index 000000000..54fe1593e
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/simple_streaming.yaml
@@ -0,0 +1,146 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 241
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"z-ai/glm-4.5","max_tokens":4000,"stream_options":{"include_usage":true},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\n","reasoning_details":[{"type":"reasoning.text","text":"\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"The","reasoning_details":[{"type":"reasoning.text","text":"The","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" person","reasoning_details":[{"type":"reasoning.text","text":" person","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" is","reasoning_details":[{"type":"reasoning.text","text":" is","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" asking","reasoning_details":[{"type":"reasoning.text","text":" asking","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" me","reasoning_details":[{"type":"reasoning.text","text":" me","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.text","text":" to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" say","reasoning_details":[{"type":"reasoning.text","text":" say","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.text","text":" \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"hi","reasoning_details":[{"type":"reasoning.text","text":"hi","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\"","reasoning_details":[{"type":"reasoning.text","text":"\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" in","reasoning_details":[{"type":"reasoning.text","text":" in","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Portuguese","reasoning_details":[{"type":"reasoning.text","text":" Portuguese","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" The","reasoning_details":[{"type":"reasoning.text","text":" The","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Portuguese","reasoning_details":[{"type":"reasoning.text","text":" Portuguese","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" word","reasoning_details":[{"type":"reasoning.text","text":" word","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.text","text":" for","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.text","text":" \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"hi","reasoning_details":[{"type":"reasoning.text","text":"hi","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\"","reasoning_details":[{"type":"reasoning.text","text":"\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" or","reasoning_details":[{"type":"reasoning.text","text":" or","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.text","text":" \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"hello","reasoning_details":[{"type":"reasoning.text","text":"hello","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\"","reasoning_details":[{"type":"reasoning.text","text":"\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" is","reasoning_details":[{"type":"reasoning.text","text":" is","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.text","text":" \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Ol","reasoning_details":[{"type":"reasoning.text","text":"Ol","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Ć”","reasoning_details":[{"type":"reasoning.text","text":"Ć”","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\".","reasoning_details":[{"type":"reasoning.text","text":"\".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.text","text":" I","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"'ll","reasoning_details":[{"type":"reasoning.text","text":"'ll","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" provide","reasoning_details":[{"type":"reasoning.text","text":" provide","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" this","reasoning_details":[{"type":"reasoning.text","text":" this","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" translation","reasoning_details":[{"type":"reasoning.text","text":" translation","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.text","text":" and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" maybe","reasoning_details":[{"type":"reasoning.text","text":" maybe","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" give","reasoning_details":[{"type":"reasoning.text","text":" give","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.text","text":" a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" little","reasoning_details":[{"type":"reasoning.text","text":" little","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" additional","reasoning_details":[{"type":"reasoning.text","text":" additional","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" context","reasoning_details":[{"type":"reasoning.text","text":" context","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" about","reasoning_details":[{"type":"reasoning.text","text":" about","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Portuguese","reasoning_details":[{"type":"reasoning.text","text":" Portuguese","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" greetings","reasoning_details":[{"type":"reasoning.text","text":" greetings","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"Hi","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":" in","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":" Portuguese","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":" is","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":" \"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"Ol","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"Ć”","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"!\"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1761054165-6sCbjZKZvMVLtzidgYHn","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054165,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":16,"completion_tokens":57,"total_tokens":73,"cost":0.00012765,"is_byok":false,"prompt_tokens_details":{"cached_tokens":15,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00000225,"upstream_inference_completions_cost":0.0001254},"completion_tokens_details":{"reasoning_tokens":52,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 474.603209ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/tool.yaml
new file mode 100644
index 000000000..12545f259
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 479
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"z-ai/glm-4.5","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054167-XemUqTQ3rOSB6BkEIie0\",\"provider\":\"Z.AI\",\"model\":\"z-ai/glm-4.5\",\"object\":\"chat.completion\",\"created\":1761054167,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\\n\",\"refusal\":null,\"reasoning\":\"\\nThe user is asking for the weather in Florence, Italy. I need to use the weather function to get this information. The function requires a \\\"location\\\" parameter, and the user has provided \\\"Florence,Italy\\\" as the location. I should use this exact value as provided by the user.\",\"tool_calls\":[{\"id\":\"call_170e2d419d2a4aba8c2a2361\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\":\\\"Florence,Italy\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"\\nThe user is asking for the weather in Florence, Italy. I need to use the weather function to get this information. The function requires a \\\"location\\\" parameter, and the user has provided \\\"Florence,Italy\\\" as the location. I should use this exact value as provided by the user.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":179,\"completion_tokens\":80,\"total_tokens\":259,\"cost\":0.00019618,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":178,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00002018,\"upstream_inference_completions_cost\":0.000176},\"completion_tokens_details\":{\"reasoning_tokens\":70,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 478.155834ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1113
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"\n","tool_calls":[{"id":"call_170e2d419d2a4aba8c2a2361","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"unknown","index":0,"text":"\nThe user is asking for the weather in Florence, Italy. I need to use the weather function to get this information. The function requires a \"location\" parameter, and the user has provided \"Florence,Italy\" as the location. I should use this exact value as provided by the user.","type":"reasoning.text"}]},{"content":"40 C","tool_call_id":"call_170e2d419d2a4aba8c2a2361","role":"tool"}],"model":"z-ai/glm-4.5","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054170-tYneB8kzk2Td9F79B6lT\",\"provider\":\"Z.AI\",\"model\":\"z-ai/glm-4.5\",\"object\":\"chat.completion\",\"created\":1761054170,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\\nThe current weather in Florence, Italy is 40°C (104°F). That's quite hot - typical summer weather for Florence, though on the warmer side. Make sure to stay hydrated and seek shade if you're planning to be outdoors!\",\"refusal\":null,\"reasoning\":\"\\nThe weather function returned \\\"40 C\\\" for Florence, Italy. This is quite hot - 40 degrees Celsius. I should provide this information to the user and perhaps add some context about what this temperature means.\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"\\nThe weather function returned \\\"40 C\\\" for Florence, Italy. This is quite hot - 40 degrees Celsius. I should provide this information to the user and perhaps add some context about what this temperature means.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":207,\"completion_tokens\":95,\"total_tokens\":302,\"cost\":0.00031213,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":43,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00010313,\"upstream_inference_completions_cost\":0.000209},\"completion_tokens_details\":{\"reasoning_tokens\":53,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 520.244083ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/tool_streaming.yaml
new file mode 100644
index 000000000..cd39b36d8
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.5/tool_streaming.yaml
@@ -0,0 +1,355 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 533
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"z-ai/glm-4.5","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\n","reasoning_details":[{"type":"reasoning.text","text":"\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"The","reasoning_details":[{"type":"reasoning.text","text":"The","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.text","text":" user","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" is","reasoning_details":[{"type":"reasoning.text","text":" is","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" asking","reasoning_details":[{"type":"reasoning.text","text":" asking","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.text","text":" for","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.text","text":" weather","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" in","reasoning_details":[{"type":"reasoning.text","text":" in","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.text","text":" Florence","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.text","text":",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Italy","reasoning_details":[{"type":"reasoning.text","text":" Italy","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.text","text":" I","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" need","reasoning_details":[{"type":"reasoning.text","text":" need","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.text","text":" to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" use","reasoning_details":[{"type":"reasoning.text","text":" use","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.text","text":" weather","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" function","reasoning_details":[{"type":"reasoning.text","text":" function","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.text","text":" to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" get","reasoning_details":[{"type":"reasoning.text","text":" get","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" this","reasoning_details":[{"type":"reasoning.text","text":" this","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" information","reasoning_details":[{"type":"reasoning.text","text":" information","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" The","reasoning_details":[{"type":"reasoning.text","text":" The","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" function","reasoning_details":[{"type":"reasoning.text","text":" function","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" requires","reasoning_details":[{"type":"reasoning.text","text":" requires","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.text","text":" a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.text","text":" \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"location","reasoning_details":[{"type":"reasoning.text","text":"location","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\"","reasoning_details":[{"type":"reasoning.text","text":"\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" parameter","reasoning_details":[{"type":"reasoning.text","text":" parameter","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.text","text":",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.text","text":" and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.text","text":" user","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" has","reasoning_details":[{"type":"reasoning.text","text":" has","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" provided","reasoning_details":[{"type":"reasoning.text","text":" provided","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.text","text":" \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Flo","reasoning_details":[{"type":"reasoning.text","text":"Flo","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"rence","reasoning_details":[{"type":"reasoning.text","text":"rence","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.text","text":",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Italy","reasoning_details":[{"type":"reasoning.text","text":"Italy","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\"","reasoning_details":[{"type":"reasoning.text","text":"\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" as","reasoning_details":[{"type":"reasoning.text","text":" as","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" location","reasoning_details":[{"type":"reasoning.text","text":" location","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.text","text":" I","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" should","reasoning_details":[{"type":"reasoning.text","text":" should","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" use","reasoning_details":[{"type":"reasoning.text","text":" use","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" this","reasoning_details":[{"type":"reasoning.text","text":" this","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" exact","reasoning_details":[{"type":"reasoning.text","text":" exact","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" value","reasoning_details":[{"type":"reasoning.text","text":" value","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.text","text":" for","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" location","reasoning_details":[{"type":"reasoning.text","text":" location","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" parameter","reasoning_details":[{"type":"reasoning.text","text":" parameter","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"call_ef1950da96ab46b19bcb66e7","index":0,"type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence,Italy\"}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}]}
+
+ data: {"id":"gen-1761054174-ERVrA11ylJ9lDokqJAho","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054174,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":179,"completion_tokens":79,"total_tokens":258,"cost":0.00019398,"is_byok":false,"prompt_tokens_details":{"cached_tokens":178,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00002018,"upstream_inference_completions_cost":0.0001738},"completion_tokens_details":{"reasoning_tokens":71,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 459.606542ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1168
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"\n","tool_calls":[{"id":"call_ef1950da96ab46b19bcb66e7","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"unknown","index":0,"text":"The user is asking for the weather in Florence, Italy. I need to use the weather function to get this information. The function requires a \"location\" parameter, and the user has provided \"Florence,Italy\" as the location. I should use this exact value for the location parameter.","type":"reasoning.text"}]},{"content":"40 C","tool_call_id":"call_ef1950da96ab46b19bcb66e7","role":"tool"}],"model":"z-ai/glm-4.5","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\n","reasoning_details":[{"type":"reasoning.text","text":"\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"The","reasoning_details":[{"type":"reasoning.text","text":"The","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.text","text":" weather","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" function","reasoning_details":[{"type":"reasoning.text","text":" function","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" returned","reasoning_details":[{"type":"reasoning.text","text":" returned","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.text","text":" \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"40","reasoning_details":[{"type":"reasoning.text","text":"40","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" C","reasoning_details":[{"type":"reasoning.text","text":" C","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\"","reasoning_details":[{"type":"reasoning.text","text":"\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.text","text":" for","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.text","text":" Florence","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.text","text":",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Italy","reasoning_details":[{"type":"reasoning.text","text":" Italy","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" This","reasoning_details":[{"type":"reasoning.text","text":" This","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" indicates","reasoning_details":[{"type":"reasoning.text","text":" indicates","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" current","reasoning_details":[{"type":"reasoning.text","text":" current","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" temperature","reasoning_details":[{"type":"reasoning.text","text":" temperature","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" is","reasoning_details":[{"type":"reasoning.text","text":" is","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.text","text":" ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"40","reasoning_details":[{"type":"reasoning.text","text":"40","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" degrees","reasoning_details":[{"type":"reasoning.text","text":" degrees","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Celsius","reasoning_details":[{"type":"reasoning.text","text":" Celsius","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.text","text":",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" which","reasoning_details":[{"type":"reasoning.text","text":" which","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" is","reasoning_details":[{"type":"reasoning.text","text":" is","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" quite","reasoning_details":[{"type":"reasoning.text","text":" quite","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" hot","reasoning_details":[{"type":"reasoning.text","text":" hot","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.text","text":" I","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" should","reasoning_details":[{"type":"reasoning.text","text":" should","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" provide","reasoning_details":[{"type":"reasoning.text","text":" provide","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" this","reasoning_details":[{"type":"reasoning.text","text":" this","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" information","reasoning_details":[{"type":"reasoning.text","text":" information","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.text","text":" to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.text","text":" user","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" in","reasoning_details":[{"type":"reasoning.text","text":" in","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.text","text":" a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" clear","reasoning_details":[{"type":"reasoning.text","text":" clear","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.text","text":" and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" helpful","reasoning_details":[{"type":"reasoning.text","text":" helpful","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" way","reasoning_details":[{"type":"reasoning.text","text":" way","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"The","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" current","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" weather","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" in","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" Florence","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":",","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" Italy","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" is","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"40","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"°C","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" (","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"104","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"°F","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":").","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" That","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"'s","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" quite","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" hot","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"!","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" Make","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" sure","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" to","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" stay","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" hydrated","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" and","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" seek","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" shade","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" if","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" you","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"'re","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":" outdoors","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":".","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1761054177-nQgmeCHWiquyCxUw9BaT","provider":"Z.AI","model":"z-ai/glm-4.5","object":"chat.completion.chunk","created":1761054177,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":207,"completion_tokens":82,"total_tokens":289,"cost":0.00020366,"is_byok":false,"prompt_tokens_details":{"cached_tokens":206,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00002326,"upstream_inference_completions_cost":0.0001804},"completion_tokens_details":{"reasoning_tokens":55,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 495.680958ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/multi_tool.yaml
new file mode 100644
index 000000000..f58b5fd61
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 842
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"z-ai/glm-4.6","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n{\"id\":\"gen-1761053358-loCOCIlvY0Hfh9vUwk5V\",\"provider\":\"GMICloud\",\"model\":\"z-ai/glm-4.6\",\"object\":\"chat.completion\",\"created\":1761053358,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\\n\\nI'll add and multiply the numbers 2 and 3 for you.\\n\\n\",\"refusal\":null,\"reasoning\":\"The user wants me to add and multiply the numbers 2 and 3. According to the instructions, I need to use both the add and multiply functions at the same time. I'll call both functions with the parameters a=2 and b=3.\",\"tool_calls\":[{\"id\":\"call_9d2eafde5e5d46f49425180b\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"add\",\"arguments\":\"{\\\"a\\\": 2, \\\"b\\\": 3}\"}},{\"id\":\"call_b54420d479364a4583f49152\",\"index\":1,\"type\":\"function\",\"function\":{\"name\":\"multiply\",\"arguments\":\"{\\\"a\\\": 2, \\\"b\\\": 3}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"The user wants me to add and multiply the numbers 2 and 3. According to the instructions, I need to use both the add and multiply functions at the same time. I'll call both functions with the parameters a=2 and b=3.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":284,\"completion_tokens\":113,\"total_tokens\":397,\"cost\":0.0003964,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0001704,\"upstream_inference_completions_cost\":0.000226},\"completion_tokens_details\":{\"reasoning_tokens\":54,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 651.927459ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1646
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"\n\nI''ll add and multiply the numbers 2 and 3 for you.\n\n","tool_calls":[{"id":"call_9d2eafde5e5d46f49425180b","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"call_b54420d479364a4583f49152","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"unknown","index":0,"text":"The user wants me to add and multiply the numbers 2 and 3. According to the instructions, I need to use both the add and multiply functions at the same time. I''ll call both functions with the parameters a=2 and b=3.","type":"reasoning.text"}]},{"content":"5","tool_call_id":"call_9d2eafde5e5d46f49425180b","role":"tool"},{"content":"6","tool_call_id":"call_b54420d479364a4583f49152","role":"tool"}],"model":"z-ai/glm-4.6","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n{\"id\":\"gen-1761053360-O9EMjlG4IrqtLYXBYnri\",\"provider\":\"Novita\",\"model\":\"z-ai/glm-4.6\",\"object\":\"chat.completion\",\"created\":1761053360,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\\nFor the numbers 2 and 3:\\n- **Addition**: 2 + 3 = 5\\n- **Multiplication**: 2 Ć 3 = 6\",\"refusal\":null,\"reasoning\":null}}],\"system_fingerprint\":\"\",\"usage\":{\"prompt_tokens\":364,\"completion_tokens\":38,\"total_tokens\":402,\"cost\":0.00028093,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":43,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00019733,\"upstream_inference_completions_cost\":0.0000836},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 763.302ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/multi_tool_streaming.yaml
new file mode 100644
index 000000000..9c962e8ce
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/multi_tool_streaming.yaml
@@ -0,0 +1,199 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 879
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"z-ai/glm-4.6","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":"I","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":"'ll","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":" help","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":" you","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":" add","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":" and","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":" multiply","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":" the","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":" numbers","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":"2","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":" and","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":"3","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":" using","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":" both","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":" operations","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":".\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"call_a28119d9b7ad43278940407d","type":"function","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"id":"call_656748576b7648529917bdb0","type":"function","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053362-Jlku9vGQnwNXMW4VZrIz","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053362,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":286,"completion_tokens":61,"total_tokens":347,"cost":0.00028473,"is_byok":false,"prompt_tokens_details":{"cached_tokens":43,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00015053,"upstream_inference_completions_cost":0.0001342},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 682.767666ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1394
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"\nI''ll help you add and multiply the numbers 2 and 3 using both operations.\n","tool_calls":[{"id":"call_a28119d9b7ad43278940407d","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"call_656748576b7648529917bdb0","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"call_a28119d9b7ad43278940407d","role":"tool"},{"content":"6","tool_call_id":"call_656748576b7648529917bdb0","role":"tool"}],"model":"z-ai/glm-4.6","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"Here","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" are","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" the","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" results","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" for","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" both","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" operations","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" with","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" the","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" numbers","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"2","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" and","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"3","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":":\n\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"**","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"Add","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"ition","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":":**","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"2","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" +","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"3","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" =","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"5","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"**","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"Multip","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"lication","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":":**","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"2","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" Ć","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"3","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" =","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"6","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761053364-vrvnS2l6PdsdIT3ZtQHo","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053364,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":363,"completion_tokens":43,"total_tokens":406,"cost":0.00029133,"is_byok":false,"prompt_tokens_details":{"cached_tokens":43,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00019673,"upstream_inference_completions_cost":0.0000946},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 789.47ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/simple.yaml
new file mode 100644
index 000000000..7920774e4
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 187
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"z-ai/glm-4.6","max_tokens":4000,"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761053318-uDEHOGKuMzvE8FP4FyMt\",\"provider\":\"GMICloud\",\"model\":\"z-ai/glm-4.6\",\"object\":\"chat.completion\",\"created\":1761053318,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\\n\\nThe most common and informal way to say \\\"hi\\\" in Portuguese is:\\n\\n**Oi!**\\n\\nYou can also use:\\n\\n**OlÔ!** (This is like \\\"Hello\\\" and is slightly more formal but used in almost any situation).\\n\\nAnd, depending on the time of day, you can say:\\n\\n* **Bom dia** - Good morning\\n* **Boa tarde** - Good afternoon\\n* **Boa noite** - Good evening / Good night\",\"refusal\":null,\"reasoning\":\"1. **Analyze the user's request:** The user wants to know how to say \\\"hi\\\" in Portuguese. This is a very simple, direct translation request.\\n\\n2. **Identify the core task:** Translate the English word \\\"hi\\\" into Portuguese.\\n\\n3. **Brainstorm Portuguese greetings:**\\n * \\\"Oi\\\" - This is the most common and direct equivalent of \\\"Hi.\\\" It's informal, friendly, and used universally in Brazil and Portugal.\\n * \\\"OlÔ\\\" - This is the equivalent of \\\"Hello.\\\" It's slightly more formal than \\\"Oi\\\" but still very common. It's a safe and polite option in any situation.\\n * \\\"E a�\\\" - This is more like \\\"What's up?\\\" or \\\"How's it going?\\\". Very informal, common among friends in Brazil. Less common in Portugal, where they might say \\\"Então?\\\" or \\\"Como estÔ?\\\".\\n * \\\"Bom dia\\\" - \\\"Good morning.\\\" Used until noon/early afternoon.\\n * \\\"Boa tarde\\\" - \\\"Good afternoon.\\\" Used from noon until sunset.\\n * \\\"Boa noite\\\" - \\\"Good evening/night.\\\" Used from sunset onwards.\\n\\n4. **Structure the answer:** I need to provide the most direct answer first, then offer context and alternatives to be more helpful.\\n\\n * **Direct Answer:** Start with the most common and direct translation. \\\"Oi\\\" is perfect for this.\\n * **Add the slightly more formal option:** \\\"OlÔ\\\" is the next best choice. I should explain the subtle difference in formality.\\n * **Provide context:** Explain *when* to use each one.\\n * \\\"Oi\\\" = informal, like \\\"Hi.\\\"\\n * \\\"OlÔ\\\" = a bit more formal, like \\\"Hello,\\\" but still widely used.\\n * **Offer more options (for a comprehensive answer):** Include time-of-day greetings (\\\"Bom dia,\\\" \\\"Boa tarde,\\\" \\\"Boa noite\\\") as they are very common and useful. Explain what each one means and when to use it.\\n * **Add a regional/cultural note:** Mentioning that \\\"Oi\\\" is very common in Brazil is a good piece of information. While it's also understood and used in Portugal, \\\"OlÔ\\\" might be slightly more common as a default greeting there. Mentioning the Brazilian \\\"E a�\\\" as a \\\"What's up?\\\" equivalent adds extra value.\\n * **Formatting:** Use bolding to make the Portuguese words stand out. Use bullet points or a clear structure to separate the different options and their explanations. This makes the information easy to digest.\\n\\n5. **Review and refine the answer:**\\n * Initial thought: Just say \\\"Oi.\\\"\\n * Better: \\\"Oi\\\" is the most common way to say \\\"hi.\\\"\\n * Even better: \\\"The most common way to say 'hi' is **Oi**.\\\" (Clear and direct).\\n * Even better still: \\\"The most common and informal way to say 'hi' in Portuguese is **Oi**.\\\" (Adds context about formality).\\n * Final plan:\\n 1. Start with \\\"**Oi**\\\" as the primary answer, explaining it's the direct equivalent of \\\"Hi\\\" and is informal.\\n 2. Follow up with \\\"**OlÔ**\\\" as the \\\"Hello\\\" equivalent, explaining it's slightly more formal but also very common.\\n 3. Add a section for time-of-day greetings: **Bom dia**, **Boa tarde**, **Boa noite**, with their English translations and usage times.\\n 4. Conclude with a friendly closing, maybe a simple \\\"Hope this helps!\\\" or something similar.\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"1. **Analyze the user's request:** The user wants to know how to say \\\"hi\\\" in Portuguese. This is a very simple, direct translation request.\\n\\n2. **Identify the core task:** Translate the English word \\\"hi\\\" into Portuguese.\\n\\n3. **Brainstorm Portuguese greetings:**\\n * \\\"Oi\\\" - This is the most common and direct equivalent of \\\"Hi.\\\" It's informal, friendly, and used universally in Brazil and Portugal.\\n * \\\"OlÔ\\\" - This is the equivalent of \\\"Hello.\\\" It's slightly more formal than \\\"Oi\\\" but still very common. It's a safe and polite option in any situation.\\n * \\\"E a�\\\" - This is more like \\\"What's up?\\\" or \\\"How's it going?\\\". Very informal, common among friends in Brazil. Less common in Portugal, where they might say \\\"Então?\\\" or \\\"Como estÔ?\\\".\\n * \\\"Bom dia\\\" - \\\"Good morning.\\\" Used until noon/early afternoon.\\n * \\\"Boa tarde\\\" - \\\"Good afternoon.\\\" Used from noon until sunset.\\n * \\\"Boa noite\\\" - \\\"Good evening/night.\\\" Used from sunset onwards.\\n\\n4. **Structure the answer:** I need to provide the most direct answer first, then offer context and alternatives to be more helpful.\\n\\n * **Direct Answer:** Start with the most common and direct translation. \\\"Oi\\\" is perfect for this.\\n * **Add the slightly more formal option:** \\\"OlÔ\\\" is the next best choice. I should explain the subtle difference in formality.\\n * **Provide context:** Explain *when* to use each one.\\n * \\\"Oi\\\" = informal, like \\\"Hi.\\\"\\n * \\\"OlÔ\\\" = a bit more formal, like \\\"Hello,\\\" but still widely used.\\n * **Offer more options (for a comprehensive answer):** Include time-of-day greetings (\\\"Bom dia,\\\" \\\"Boa tarde,\\\" \\\"Boa noite\\\") as they are very common and useful. Explain what each one means and when to use it.\\n * **Add a regional/cultural note:** Mentioning that \\\"Oi\\\" is very common in Brazil is a good piece of information. While it's also understood and used in Portugal, \\\"OlÔ\\\" might be slightly more common as a default greeting there. Mentioning the Brazilian \\\"E a�\\\" as a \\\"What's up?\\\" equivalent adds extra value.\\n * **Formatting:** Use bolding to make the Portuguese words stand out. Use bullet points or a clear structure to separate the different options and their explanations. This makes the information easy to digest.\\n\\n5. **Review and refine the answer:**\\n * Initial thought: Just say \\\"Oi.\\\"\\n * Better: \\\"Oi\\\" is the most common way to say \\\"hi.\\\"\\n * Even better: \\\"The most common way to say 'hi' is **Oi**.\\\" (Clear and direct).\\n * Even better still: \\\"The most common and informal way to say 'hi' in Portuguese is **Oi**.\\\" (Adds context about formality).\\n * Final plan:\\n 1. Start with \\\"**Oi**\\\" as the primary answer, explaining it's the direct equivalent of \\\"Hi\\\" and is informal.\\n 2. Follow up with \\\"**OlÔ**\\\" as the \\\"Hello\\\" equivalent, explaining it's slightly more formal but also very common.\\n 3. Add a section for time-of-day greetings: **Bom dia**, **Boa tarde**, **Boa noite**, with their English translations and usage times.\\n 4. Conclude with a friendly closing, maybe a simple \\\"Hope this helps!\\\" or something similar.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":16,\"completion_tokens\":883,\"total_tokens\":899,\"cost\":0.0017756,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000096,\"upstream_inference_completions_cost\":0.001766},\"completion_tokens_details\":{\"reasoning_tokens\":810,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 877.441834ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/simple_streaming.yaml
new file mode 100644
index 000000000..d96d8961d
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/simple_streaming.yaml
@@ -0,0 +1,1354 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 241
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"z-ai/glm-4.6","max_tokens":4000,"stream_options":{"include_usage":true},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"1","reasoning_details":[{"type":"reasoning.text","text":"1","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":". ","reasoning_details":[{"type":"reasoning.text","text":". ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **An","reasoning_details":[{"type":"reasoning.text","text":" **An","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"alyze the","reasoning_details":[{"type":"reasoning.text","text":"alyze the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" User","reasoning_details":[{"type":"reasoning.text","text":" User","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"'s Request","reasoning_details":[{"type":"reasoning.text","text":"'s Request","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":":** The","reasoning_details":[{"type":"reasoning.text","text":":** The","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user wants","reasoning_details":[{"type":"reasoning.text","text":" user wants","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to know","reasoning_details":[{"type":"reasoning.text","text":" to know","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" how to","reasoning_details":[{"type":"reasoning.text","text":" how to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" say \"","reasoning_details":[{"type":"reasoning.text","text":" say \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"hi\"","reasoning_details":[{"type":"reasoning.text","text":"hi\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" in Portuguese","reasoning_details":[{"type":"reasoning.text","text":" in Portuguese","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":". This","reasoning_details":[{"type":"reasoning.text","text":". This","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" is a","reasoning_details":[{"type":"reasoning.text","text":" is a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" very simple","reasoning_details":[{"type":"reasoning.text","text":" very simple","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":", direct","reasoning_details":[{"type":"reasoning.text","text":", direct","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" translation request","reasoning_details":[{"type":"reasoning.text","text":" translation request","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".\n\n2","reasoning_details":[{"type":"reasoning.text","text":".\n\n2","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":". ","reasoning_details":[{"type":"reasoning.text","text":". ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **Ident","reasoning_details":[{"type":"reasoning.text","text":" **Ident","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ify the","reasoning_details":[{"type":"reasoning.text","text":"ify the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Core Task","reasoning_details":[{"type":"reasoning.text","text":" Core Task","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":":** The","reasoning_details":[{"type":"reasoning.text","text":":** The","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" task is","reasoning_details":[{"type":"reasoning.text","text":" task is","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to provide","reasoning_details":[{"type":"reasoning.text","text":" to provide","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the Portuguese","reasoning_details":[{"type":"reasoning.text","text":" the Portuguese","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" equivalent","reasoning_details":[{"type":"reasoning.text","text":" equivalent","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" of the","reasoning_details":[{"type":"reasoning.text","text":" of the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" English greeting","reasoning_details":[{"type":"reasoning.text","text":" English greeting","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"hi","reasoning_details":[{"type":"reasoning.text","text":" \"hi","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\".\n\n3","reasoning_details":[{"type":"reasoning.text","text":"\".\n\n3","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":". ","reasoning_details":[{"type":"reasoning.text","text":". ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **Brain","reasoning_details":[{"type":"reasoning.text","text":" **Brain","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"storm Portuguese","reasoning_details":[{"type":"reasoning.text","text":"storm Portuguese","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" G","reasoning_details":[{"type":"reasoning.text","text":" G","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"reetings:","reasoning_details":[{"type":"reasoning.text","text":"reetings:","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"**\n ","reasoning_details":[{"type":"reasoning.text","text":"**\n ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" * ","reasoning_details":[{"type":"reasoning.text","text":" * ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.text","text":" \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Oi","reasoning_details":[{"type":"reasoning.text","text":"Oi","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\" -","reasoning_details":[{"type":"reasoning.text","text":"\" -","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" This is","reasoning_details":[{"type":"reasoning.text","text":" This is","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the most","reasoning_details":[{"type":"reasoning.text","text":" the most","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" direct and","reasoning_details":[{"type":"reasoning.text","text":" direct and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" common translation","reasoning_details":[{"type":"reasoning.text","text":" common translation","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" of \"","reasoning_details":[{"type":"reasoning.text","text":" of \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"hi","reasoning_details":[{"type":"reasoning.text","text":"hi","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\". It","reasoning_details":[{"type":"reasoning.text","text":"\". It","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"'s informal","reasoning_details":[{"type":"reasoning.text","text":"'s informal","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":", friendly","reasoning_details":[{"type":"reasoning.text","text":", friendly","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":", and","reasoning_details":[{"type":"reasoning.text","text":", and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" used everywhere","reasoning_details":[{"type":"reasoning.text","text":" used everywhere","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" in Brazil","reasoning_details":[{"type":"reasoning.text","text":" in Brazil","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and Portugal","reasoning_details":[{"type":"reasoning.text","text":" and Portugal","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":". It","reasoning_details":[{"type":"reasoning.text","text":". It","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"'s the","reasoning_details":[{"type":"reasoning.text","text":"'s the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" perfect primary","reasoning_details":[{"type":"reasoning.text","text":" perfect primary","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" answer.\n","reasoning_details":[{"type":"reasoning.text","text":" answer.\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *","reasoning_details":[{"type":"reasoning.text","text":" *","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.text","text":" \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"OlĆ”","reasoning_details":[{"type":"reasoning.text","text":"OlĆ”","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\" -","reasoning_details":[{"type":"reasoning.text","text":"\" -","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" This is","reasoning_details":[{"type":"reasoning.text","text":" This is","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the equivalent","reasoning_details":[{"type":"reasoning.text","text":" the equivalent","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" of \"","reasoning_details":[{"type":"reasoning.text","text":" of \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Hello\".","reasoning_details":[{"type":"reasoning.text","text":"Hello\".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" It's","reasoning_details":[{"type":"reasoning.text","text":" It's","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" slightly more","reasoning_details":[{"type":"reasoning.text","text":" slightly more","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" formal than","reasoning_details":[{"type":"reasoning.text","text":" formal than","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"Oi","reasoning_details":[{"type":"reasoning.text","text":" \"Oi","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\" but","reasoning_details":[{"type":"reasoning.text","text":"\" but","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" still very","reasoning_details":[{"type":"reasoning.text","text":" still very","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" common and","reasoning_details":[{"type":"reasoning.text","text":" common and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" perfectly acceptable","reasoning_details":[{"type":"reasoning.text","text":" perfectly acceptable","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" in almost","reasoning_details":[{"type":"reasoning.text","text":" in almost","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" any situation.","reasoning_details":[{"type":"reasoning.text","text":" any situation.","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" It's","reasoning_details":[{"type":"reasoning.text","text":" It's","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a great","reasoning_details":[{"type":"reasoning.text","text":" a great","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" alternative to","reasoning_details":[{"type":"reasoning.text","text":" alternative to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" provide","reasoning_details":[{"type":"reasoning.text","text":" provide","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".\n ","reasoning_details":[{"type":"reasoning.text","text":".\n ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" * ","reasoning_details":[{"type":"reasoning.text","text":" * ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"E","reasoning_details":[{"type":"reasoning.text","text":" \"E","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" aĆ","reasoning_details":[{"type":"reasoning.text","text":" aĆ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"?\"","reasoning_details":[{"type":"reasoning.text","text":"?\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" - This","reasoning_details":[{"type":"reasoning.text","text":" - This","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" is more","reasoning_details":[{"type":"reasoning.text","text":" is more","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" like \"","reasoning_details":[{"type":"reasoning.text","text":" like \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"What's","reasoning_details":[{"type":"reasoning.text","text":"What's","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" up?\" or","reasoning_details":[{"type":"reasoning.text","text":" up?\" or","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"Hey","reasoning_details":[{"type":"reasoning.text","text":" \"Hey","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" there?","reasoning_details":[{"type":"reasoning.text","text":" there?","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\". It","reasoning_details":[{"type":"reasoning.text","text":"\". It","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"'s very","reasoning_details":[{"type":"reasoning.text","text":"'s very","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" informal,","reasoning_details":[{"type":"reasoning.text","text":" informal,","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" common in","reasoning_details":[{"type":"reasoning.text","text":" common in","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Brazil.","reasoning_details":[{"type":"reasoning.text","text":" Brazil.","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" It's","reasoning_details":[{"type":"reasoning.text","text":" It's","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a good","reasoning_details":[{"type":"reasoning.text","text":" a good","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" secondary option","reasoning_details":[{"type":"reasoning.text","text":" secondary option","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to show","reasoning_details":[{"type":"reasoning.text","text":" to show","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" more nu","reasoning_details":[{"type":"reasoning.text","text":" more nu","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ance.\n","reasoning_details":[{"type":"reasoning.text","text":"ance.\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *","reasoning_details":[{"type":"reasoning.text","text":" *","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.text","text":" \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Tudo","reasoning_details":[{"type":"reasoning.text","text":"Tudo","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" bem?\"","reasoning_details":[{"type":"reasoning.text","text":" bem?\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" -","reasoning_details":[{"type":"reasoning.text","text":" -","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" This means","reasoning_details":[{"type":"reasoning.text","text":" This means","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"All","reasoning_details":[{"type":"reasoning.text","text":" \"All","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" good?\"","reasoning_details":[{"type":"reasoning.text","text":" good?\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" or \"","reasoning_details":[{"type":"reasoning.text","text":" or \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"How are","reasoning_details":[{"type":"reasoning.text","text":"How are","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" you?\".","reasoning_details":[{"type":"reasoning.text","text":" you?\".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" It's","reasoning_details":[{"type":"reasoning.text","text":" It's","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" often used","reasoning_details":[{"type":"reasoning.text","text":" often used","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *","reasoning_details":[{"type":"reasoning.text","text":" *","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"as*","reasoning_details":[{"type":"reasoning.text","text":"as*","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a greeting","reasoning_details":[{"type":"reasoning.text","text":" a greeting","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":", similar","reasoning_details":[{"type":"reasoning.text","text":", similar","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to \"","reasoning_details":[{"type":"reasoning.text","text":" to \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"How's","reasoning_details":[{"type":"reasoning.text","text":"How's","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" it going?","reasoning_details":[{"type":"reasoning.text","text":" it going?","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\". Another","reasoning_details":[{"type":"reasoning.text","text":"\". Another","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" good,","reasoning_details":[{"type":"reasoning.text","text":" good,","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" slightly","reasoning_details":[{"type":"reasoning.text","text":" slightly","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" more advanced","reasoning_details":[{"type":"reasoning.text","text":" more advanced","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" option","reasoning_details":[{"type":"reasoning.text","text":" option","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".\n ","reasoning_details":[{"type":"reasoning.text","text":".\n ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" * ","reasoning_details":[{"type":"reasoning.text","text":" * ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"B","reasoning_details":[{"type":"reasoning.text","text":" \"B","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"om dia","reasoning_details":[{"type":"reasoning.text","text":"om dia","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\" /","reasoning_details":[{"type":"reasoning.text","text":"\" /","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"Bo","reasoning_details":[{"type":"reasoning.text","text":" \"Bo","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"a tarde","reasoning_details":[{"type":"reasoning.text","text":"a tarde","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\" /","reasoning_details":[{"type":"reasoning.text","text":"\" /","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"Bo","reasoning_details":[{"type":"reasoning.text","text":" \"Bo","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"a noite","reasoning_details":[{"type":"reasoning.text","text":"a noite","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\" -","reasoning_details":[{"type":"reasoning.text","text":"\" -","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" These","reasoning_details":[{"type":"reasoning.text","text":" These","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" are \"","reasoning_details":[{"type":"reasoning.text","text":" are \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Good morning\",","reasoning_details":[{"type":"reasoning.text","text":"Good morning\",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"Good","reasoning_details":[{"type":"reasoning.text","text":" \"Good","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" afternoon\",","reasoning_details":[{"type":"reasoning.text","text":" afternoon\",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and \"","reasoning_details":[{"type":"reasoning.text","text":" and \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Good night","reasoning_details":[{"type":"reasoning.text","text":"Good night","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"/even","reasoning_details":[{"type":"reasoning.text","text":"/even","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ing\".","reasoning_details":[{"type":"reasoning.text","text":"ing\".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" They are","reasoning_details":[{"type":"reasoning.text","text":" They are","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" also","reasoning_details":[{"type":"reasoning.text","text":" also","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" greetings","reasoning_details":[{"type":"reasoning.text","text":" greetings","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.text","text":",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" but they","reasoning_details":[{"type":"reasoning.text","text":" but they","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" are time","reasoning_details":[{"type":"reasoning.text","text":" are time","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"-specific","reasoning_details":[{"type":"reasoning.text","text":"-specific","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":". While","reasoning_details":[{"type":"reasoning.text","text":". While","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" not a","reasoning_details":[{"type":"reasoning.text","text":" not a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" direct translation","reasoning_details":[{"type":"reasoning.text","text":" direct translation","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" of \"","reasoning_details":[{"type":"reasoning.text","text":" of \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"hi\",","reasoning_details":[{"type":"reasoning.text","text":"hi\",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" they are","reasoning_details":[{"type":"reasoning.text","text":" they are","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" essential","reasoning_details":[{"type":"reasoning.text","text":" essential","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" greetings in","reasoning_details":[{"type":"reasoning.text","text":" greetings in","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Portuguese and","reasoning_details":[{"type":"reasoning.text","text":" Portuguese and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" worth mentioning","reasoning_details":[{"type":"reasoning.text","text":" worth mentioning","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.text","text":" for","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.text","text":" a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" more","reasoning_details":[{"type":"reasoning.text","text":" more","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" complete answer","reasoning_details":[{"type":"reasoning.text","text":" complete answer","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".\n\n4","reasoning_details":[{"type":"reasoning.text","text":".\n\n4","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":". ","reasoning_details":[{"type":"reasoning.text","text":". ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **Structure","reasoning_details":[{"type":"reasoning.text","text":" **Structure","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the Answer","reasoning_details":[{"type":"reasoning.text","text":" the Answer","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":":** A","reasoning_details":[{"type":"reasoning.text","text":":** A","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" good answer","reasoning_details":[{"type":"reasoning.text","text":" good answer","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" should be","reasoning_details":[{"type":"reasoning.text","text":" should be","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" clear,","reasoning_details":[{"type":"reasoning.text","text":" clear,","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" helpful","reasoning_details":[{"type":"reasoning.text","text":" helpful","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":", and","reasoning_details":[{"type":"reasoning.text","text":", and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" provide context","reasoning_details":[{"type":"reasoning.text","text":" provide context","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I'll","reasoning_details":[{"type":"reasoning.text","text":" I'll","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" structure it","reasoning_details":[{"type":"reasoning.text","text":" structure it","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" like this","reasoning_details":[{"type":"reasoning.text","text":" like this","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":":\n\n ","reasoning_details":[{"type":"reasoning.text","text":":\n\n ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" * ","reasoning_details":[{"type":"reasoning.text","text":" * ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **Direct","reasoning_details":[{"type":"reasoning.text","text":" **Direct","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Answer First","reasoning_details":[{"type":"reasoning.text","text":" Answer First","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":":** Start","reasoning_details":[{"type":"reasoning.text","text":":** Start","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" with the","reasoning_details":[{"type":"reasoning.text","text":" with the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" most common","reasoning_details":[{"type":"reasoning.text","text":" most common","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and direct","reasoning_details":[{"type":"reasoning.text","text":" and direct","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" translation.","reasoning_details":[{"type":"reasoning.text","text":" translation.","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" This immediately","reasoning_details":[{"type":"reasoning.text","text":" This immediately","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" satisfies the","reasoning_details":[{"type":"reasoning.text","text":" satisfies the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user's","reasoning_details":[{"type":"reasoning.text","text":" user's","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" request.","reasoning_details":[{"type":"reasoning.text","text":" request.","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"Oi","reasoning_details":[{"type":"reasoning.text","text":" \"Oi","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"!\" is","reasoning_details":[{"type":"reasoning.text","text":"!\" is","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the best","reasoning_details":[{"type":"reasoning.text","text":" the best","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" choice.\n","reasoning_details":[{"type":"reasoning.text","text":" choice.\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *","reasoning_details":[{"type":"reasoning.text","text":" *","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **","reasoning_details":[{"type":"reasoning.text","text":" **","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Provide a","reasoning_details":[{"type":"reasoning.text","text":"Provide a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" S","reasoning_details":[{"type":"reasoning.text","text":" S","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"lightly More","reasoning_details":[{"type":"reasoning.text","text":"lightly More","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Formal Alternative:**","reasoning_details":[{"type":"reasoning.text","text":" Formal Alternative:**","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Int","reasoning_details":[{"type":"reasoning.text","text":" Int","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"roduce \"","reasoning_details":[{"type":"reasoning.text","text":"roduce \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"OlĆ”","reasoning_details":[{"type":"reasoning.text","text":"OlĆ”","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\"","reasoning_details":[{"type":"reasoning.text","text":"\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" as","reasoning_details":[{"type":"reasoning.text","text":" as","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"Hello","reasoning_details":[{"type":"reasoning.text","text":" \"Hello","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\" equivalent","reasoning_details":[{"type":"reasoning.text","text":"\" equivalent","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":". Explain","reasoning_details":[{"type":"reasoning.text","text":". Explain","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the subtle","reasoning_details":[{"type":"reasoning.text","text":" the subtle","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" difference in","reasoning_details":[{"type":"reasoning.text","text":" difference in","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" formality","reasoning_details":[{"type":"reasoning.text","text":" formality","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":". This","reasoning_details":[{"type":"reasoning.text","text":". This","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" adds value","reasoning_details":[{"type":"reasoning.text","text":" adds value","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".\n ","reasoning_details":[{"type":"reasoning.text","text":".\n ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" * ","reasoning_details":[{"type":"reasoning.text","text":" * ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **Add","reasoning_details":[{"type":"reasoning.text","text":" **Add","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" More","reasoning_details":[{"type":"reasoning.text","text":" More","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Casual","reasoning_details":[{"type":"reasoning.text","text":" Casual","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"/Context","reasoning_details":[{"type":"reasoning.text","text":"/Context","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ual Options","reasoning_details":[{"type":"reasoning.text","text":"ual Options","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":":** Include","reasoning_details":[{"type":"reasoning.text","text":":** Include","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" greetings","reasoning_details":[{"type":"reasoning.text","text":" greetings","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" like \"","reasoning_details":[{"type":"reasoning.text","text":" like \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"E a","reasoning_details":[{"type":"reasoning.text","text":"E a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Ć?\"","reasoning_details":[{"type":"reasoning.text","text":"Ć?\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and \"","reasoning_details":[{"type":"reasoning.text","text":" and \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Tudo","reasoning_details":[{"type":"reasoning.text","text":"Tudo","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" bem?\".","reasoning_details":[{"type":"reasoning.text","text":" bem?\".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" This shows","reasoning_details":[{"type":"reasoning.text","text":" This shows","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a deeper","reasoning_details":[{"type":"reasoning.text","text":" a deeper","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" understanding of the","reasoning_details":[{"type":"reasoning.text","text":" understanding of the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" language and","reasoning_details":[{"type":"reasoning.text","text":" language and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" how people","reasoning_details":[{"type":"reasoning.text","text":" how people","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" actually speak","reasoning_details":[{"type":"reasoning.text","text":" actually speak","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":". I","reasoning_details":[{"type":"reasoning.text","text":". I","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" should explain","reasoning_details":[{"type":"reasoning.text","text":" should explain","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" what they","reasoning_details":[{"type":"reasoning.text","text":" what they","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" mean (\"","reasoning_details":[{"type":"reasoning.text","text":" mean (\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"What's","reasoning_details":[{"type":"reasoning.text","text":"What's","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" up?\", \"","reasoning_details":[{"type":"reasoning.text","text":" up?\", \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"How are","reasoning_details":[{"type":"reasoning.text","text":"How are","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" you?","reasoning_details":[{"type":"reasoning.text","text":" you?","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\").\n ","reasoning_details":[{"type":"reasoning.text","text":"\").\n ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" * ","reasoning_details":[{"type":"reasoning.text","text":" * ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **M","reasoning_details":[{"type":"reasoning.text","text":" **M","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ention Time","reasoning_details":[{"type":"reasoning.text","text":"ention Time","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"-of","reasoning_details":[{"type":"reasoning.text","text":"-of","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"-Day Greetings","reasoning_details":[{"type":"reasoning.text","text":"-Day Greetings","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":":** Include","reasoning_details":[{"type":"reasoning.text","text":":** Include","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"B","reasoning_details":[{"type":"reasoning.text","text":" \"B","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"om dia,\"","reasoning_details":[{"type":"reasoning.text","text":"om dia,\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"Bo","reasoning_details":[{"type":"reasoning.text","text":" \"Bo","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"a tarde","reasoning_details":[{"type":"reasoning.text","text":"a tarde","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",\" and","reasoning_details":[{"type":"reasoning.text","text":",\" and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"Bo","reasoning_details":[{"type":"reasoning.text","text":" \"Bo","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"a noite","reasoning_details":[{"type":"reasoning.text","text":"a noite","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".\" This","reasoning_details":[{"type":"reasoning.text","text":".\" This","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" is crucial","reasoning_details":[{"type":"reasoning.text","text":" is crucial","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for anyone","reasoning_details":[{"type":"reasoning.text","text":" for anyone","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" actually","reasoning_details":[{"type":"reasoning.text","text":" actually","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" trying to","reasoning_details":[{"type":"reasoning.text","text":" trying to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" speak","reasoning_details":[{"type":"reasoning.text","text":" speak","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Portuguese.","reasoning_details":[{"type":"reasoning.text","text":" Portuguese.","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I'll","reasoning_details":[{"type":"reasoning.text","text":" I'll","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" translate","reasoning_details":[{"type":"reasoning.text","text":" translate","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" them and","reasoning_details":[{"type":"reasoning.text","text":" them and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" explain when","reasoning_details":[{"type":"reasoning.text","text":" explain when","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to use","reasoning_details":[{"type":"reasoning.text","text":" to use","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" them.\n","reasoning_details":[{"type":"reasoning.text","text":" them.\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *","reasoning_details":[{"type":"reasoning.text","text":" *","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **","reasoning_details":[{"type":"reasoning.text","text":" **","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Add a","reasoning_details":[{"type":"reasoning.text","text":"Add a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Regional","reasoning_details":[{"type":"reasoning.text","text":" Regional","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Note (","reasoning_details":[{"type":"reasoning.text","text":" Note (","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Optional but","reasoning_details":[{"type":"reasoning.text","text":"Optional but","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" good):","reasoning_details":[{"type":"reasoning.text","text":" good):","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"** Brief","reasoning_details":[{"type":"reasoning.text","text":"** Brief","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ly mention","reasoning_details":[{"type":"reasoning.text","text":"ly mention","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" that \"","reasoning_details":[{"type":"reasoning.text","text":" that \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Oi\"","reasoning_details":[{"type":"reasoning.text","text":"Oi\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" is extremely","reasoning_details":[{"type":"reasoning.text","text":" is extremely","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" common in","reasoning_details":[{"type":"reasoning.text","text":" common in","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Brazil.","reasoning_details":[{"type":"reasoning.text","text":" Brazil.","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" While also","reasoning_details":[{"type":"reasoning.text","text":" While also","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" used in","reasoning_details":[{"type":"reasoning.text","text":" used in","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Portugal, \"","reasoning_details":[{"type":"reasoning.text","text":" Portugal, \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"OlĆ”","reasoning_details":[{"type":"reasoning.text","text":"OlĆ”","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\" might","reasoning_details":[{"type":"reasoning.text","text":"\" might","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" be slightly","reasoning_details":[{"type":"reasoning.text","text":" be slightly","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" more common","reasoning_details":[{"type":"reasoning.text","text":" more common","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" as a","reasoning_details":[{"type":"reasoning.text","text":" as a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" general greeting","reasoning_details":[{"type":"reasoning.text","text":" general greeting","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" there.","reasoning_details":[{"type":"reasoning.text","text":" there.","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" This adds","reasoning_details":[{"type":"reasoning.text","text":" This adds","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a layer","reasoning_details":[{"type":"reasoning.text","text":" a layer","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" of expertise","reasoning_details":[{"type":"reasoning.text","text":" of expertise","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":". (","reasoning_details":[{"type":"reasoning.text","text":". (","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Self","reasoning_details":[{"type":"reasoning.text","text":"Self","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"-correction","reasoning_details":[{"type":"reasoning.text","text":"-correction","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":": Keep","reasoning_details":[{"type":"reasoning.text","text":": Keep","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" this","reasoning_details":[{"type":"reasoning.text","text":" this","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" simple.","reasoning_details":[{"type":"reasoning.text","text":" simple.","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Over","reasoning_details":[{"type":"reasoning.text","text":" Over","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"complic","reasoning_details":[{"type":"reasoning.text","text":"complic","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ating with","reasoning_details":[{"type":"reasoning.text","text":"ating with","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" deep","reasoning_details":[{"type":"reasoning.text","text":" deep","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" regional dialect","reasoning_details":[{"type":"reasoning.text","text":" regional dialect","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"s might","reasoning_details":[{"type":"reasoning.text","text":"s might","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" confuse a","reasoning_details":[{"type":"reasoning.text","text":" confuse a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" beginner.","reasoning_details":[{"type":"reasoning.text","text":" beginner.","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" A simple","reasoning_details":[{"type":"reasoning.text","text":" A simple","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" mention","reasoning_details":[{"type":"reasoning.text","text":" mention","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" is enough","reasoning_details":[{"type":"reasoning.text","text":" is enough","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":").\n ","reasoning_details":[{"type":"reasoning.text","text":").\n ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" * ","reasoning_details":[{"type":"reasoning.text","text":" * ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **Sum","reasoning_details":[{"type":"reasoning.text","text":" **Sum","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"marize/","reasoning_details":[{"type":"reasoning.text","text":"marize/","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Con","reasoning_details":[{"type":"reasoning.text","text":"Con","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"clude:**","reasoning_details":[{"type":"reasoning.text","text":"clude:**","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" End with","reasoning_details":[{"type":"reasoning.text","text":" End with","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a friendly","reasoning_details":[{"type":"reasoning.text","text":" a friendly","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" closing,","reasoning_details":[{"type":"reasoning.text","text":" closing,","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" like \"","reasoning_details":[{"type":"reasoning.text","text":" like \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"So,","reasoning_details":[{"type":"reasoning.text","text":"So,","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" you can","reasoning_details":[{"type":"reasoning.text","text":" you can","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"'t","reasoning_details":[{"type":"reasoning.text","text":"'t","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" go wrong with","reasoning_details":[{"type":"reasoning.text","text":" go wrong with","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" 'Oi","reasoning_details":[{"type":"reasoning.text","text":" 'Oi","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"' or","reasoning_details":[{"type":"reasoning.text","text":"' or","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" 'Ol","reasoning_details":[{"type":"reasoning.text","text":" 'Ol","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Ć”'","reasoning_details":[{"type":"reasoning.text","text":"Ć”'","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"!\" to","reasoning_details":[{"type":"reasoning.text","text":"!\" to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" reinforce the","reasoning_details":[{"type":"reasoning.text","text":" reinforce the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" main points","reasoning_details":[{"type":"reasoning.text","text":" main points","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and be","reasoning_details":[{"type":"reasoning.text","text":" and be","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" encouraging.\n\n","reasoning_details":[{"type":"reasoning.text","text":" encouraging.\n\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"5.","reasoning_details":[{"type":"reasoning.text","text":"5.","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **","reasoning_details":[{"type":"reasoning.text","text":" **","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Draft the","reasoning_details":[{"type":"reasoning.text","text":"Draft the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" final","reasoning_details":[{"type":"reasoning.text","text":" final","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" response based","reasoning_details":[{"type":"reasoning.text","text":" response based","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" on the","reasoning_details":[{"type":"reasoning.text","text":" on the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" structure:","reasoning_details":[{"type":"reasoning.text","text":" structure:","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"**\n\n ","reasoning_details":[{"type":"reasoning.text","text":"**\n\n ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" * ","reasoning_details":[{"type":"reasoning.text","text":" * ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *Start","reasoning_details":[{"type":"reasoning.text","text":" *Start","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" with \"","reasoning_details":[{"type":"reasoning.text","text":" with \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Oi!\"","reasoning_details":[{"type":"reasoning.text","text":"Oi!\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"* -","reasoning_details":[{"type":"reasoning.text","text":"* -","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" The","reasoning_details":[{"type":"reasoning.text","text":" The","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" most common","reasoning_details":[{"type":"reasoning.text","text":" most common","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and direct","reasoning_details":[{"type":"reasoning.text","text":" and direct","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" way to","reasoning_details":[{"type":"reasoning.text","text":" way to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" say \"","reasoning_details":[{"type":"reasoning.text","text":" say \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"hi\".\n","reasoning_details":[{"type":"reasoning.text","text":"hi\".\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *","reasoning_details":[{"type":"reasoning.text","text":" *","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *","reasoning_details":[{"type":"reasoning.text","text":" *","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Add \"","reasoning_details":[{"type":"reasoning.text","text":"Add \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"OlĆ”","reasoning_details":[{"type":"reasoning.text","text":"OlĆ”","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".\"*","reasoning_details":[{"type":"reasoning.text","text":".\"*","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" - Explain","reasoning_details":[{"type":"reasoning.text","text":" - Explain","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" it's","reasoning_details":[{"type":"reasoning.text","text":" it's","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" like \"","reasoning_details":[{"type":"reasoning.text","text":" like \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Hello\",","reasoning_details":[{"type":"reasoning.text","text":"Hello\",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a bit","reasoning_details":[{"type":"reasoning.text","text":" a bit","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" more formal","reasoning_details":[{"type":"reasoning.text","text":" more formal","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" but still","reasoning_details":[{"type":"reasoning.text","text":" but still","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" very common","reasoning_details":[{"type":"reasoning.text","text":" very common","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".\n ","reasoning_details":[{"type":"reasoning.text","text":".\n ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" * ","reasoning_details":[{"type":"reasoning.text","text":" * ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *Create","reasoning_details":[{"type":"reasoning.text","text":" *Create","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a list","reasoning_details":[{"type":"reasoning.text","text":" a list","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" or","reasoning_details":[{"type":"reasoning.text","text":" or","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" bullet","reasoning_details":[{"type":"reasoning.text","text":" bullet","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" points for","reasoning_details":[{"type":"reasoning.text","text":" points for","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" clarity.*\n","reasoning_details":[{"type":"reasoning.text","text":" clarity.*\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *","reasoning_details":[{"type":"reasoning.text","text":" *","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **","reasoning_details":[{"type":"reasoning.text","text":" **","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Oi!","reasoning_details":[{"type":"reasoning.text","text":"Oi!","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"** (","reasoning_details":[{"type":"reasoning.text","text":"** (","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"oh","reasoning_details":[{"type":"reasoning.text","text":"oh","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"-","reasoning_details":[{"type":"reasoning.text","text":"-","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ee) -","reasoning_details":[{"type":"reasoning.text","text":"ee) -","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" The most","reasoning_details":[{"type":"reasoning.text","text":" The most","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" common,","reasoning_details":[{"type":"reasoning.text","text":" common,","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" informal \"","reasoning_details":[{"type":"reasoning.text","text":" informal \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"hi","reasoning_details":[{"type":"reasoning.text","text":"hi","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\".\n ","reasoning_details":[{"type":"reasoning.text","text":"\".\n ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" * ","reasoning_details":[{"type":"reasoning.text","text":" * ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **Ol","reasoning_details":[{"type":"reasoning.text","text":" **Ol","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Ć”.","reasoning_details":[{"type":"reasoning.text","text":"Ć”.","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"** (","reasoning_details":[{"type":"reasoning.text","text":"** (","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"oh-L","reasoning_details":[{"type":"reasoning.text","text":"oh-L","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"AH)","reasoning_details":[{"type":"reasoning.text","text":"AH)","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" - The","reasoning_details":[{"type":"reasoning.text","text":" - The","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" standard","reasoning_details":[{"type":"reasoning.text","text":" standard","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"hello","reasoning_details":[{"type":"reasoning.text","text":" \"hello","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\", a","reasoning_details":[{"type":"reasoning.text","text":"\", a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" little","reasoning_details":[{"type":"reasoning.text","text":" little","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" more formal","reasoning_details":[{"type":"reasoning.text","text":" more formal","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" but","reasoning_details":[{"type":"reasoning.text","text":" but","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" used","reasoning_details":[{"type":"reasoning.text","text":" used","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" everywhere.\n","reasoning_details":[{"type":"reasoning.text","text":" everywhere.\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *","reasoning_details":[{"type":"reasoning.text","text":" *","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *","reasoning_details":[{"type":"reasoning.text","text":" *","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Add a","reasoning_details":[{"type":"reasoning.text","text":"Add a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" section for","reasoning_details":[{"type":"reasoning.text","text":" section for","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" other","reasoning_details":[{"type":"reasoning.text","text":" other","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" common greetings","reasoning_details":[{"type":"reasoning.text","text":" common greetings","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".*\n ","reasoning_details":[{"type":"reasoning.text","text":".*\n ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" * ","reasoning_details":[{"type":"reasoning.text","text":" * ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **E","reasoning_details":[{"type":"reasoning.text","text":" **E","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" aĆ?","reasoning_details":[{"type":"reasoning.text","text":" aĆ?","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"** (","reasoning_details":[{"type":"reasoning.text","text":"** (","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"eh ah","reasoning_details":[{"type":"reasoning.text","text":"eh ah","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"-EE?)","reasoning_details":[{"type":"reasoning.text","text":"-EE?)","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" - \"","reasoning_details":[{"type":"reasoning.text","text":" - \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"What's","reasoning_details":[{"type":"reasoning.text","text":"What's","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" up?\"","reasoning_details":[{"type":"reasoning.text","text":" up?\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" (very","reasoning_details":[{"type":"reasoning.text","text":" (very","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" informal,","reasoning_details":[{"type":"reasoning.text","text":" informal,","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" mostly","reasoning_details":[{"type":"reasoning.text","text":" mostly","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" in Brazil","reasoning_details":[{"type":"reasoning.text","text":" in Brazil","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":").\n ","reasoning_details":[{"type":"reasoning.text","text":").\n ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" * ","reasoning_details":[{"type":"reasoning.text","text":" * ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **T","reasoning_details":[{"type":"reasoning.text","text":" **T","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"udo bem?","reasoning_details":[{"type":"reasoning.text","text":"udo bem?","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"** (","reasoning_details":[{"type":"reasoning.text","text":"** (","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"TOO","reasoning_details":[{"type":"reasoning.text","text":"TOO","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"-doo b","reasoning_details":[{"type":"reasoning.text","text":"-doo b","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"eng?)","reasoning_details":[{"type":"reasoning.text","text":"eng?)","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" - \"","reasoning_details":[{"type":"reasoning.text","text":" - \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"All good","reasoning_details":[{"type":"reasoning.text","text":"All good","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"?\" or","reasoning_details":[{"type":"reasoning.text","text":"?\" or","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"How","reasoning_details":[{"type":"reasoning.text","text":" \"How","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" are you","reasoning_details":[{"type":"reasoning.text","text":" are you","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"?\" (","reasoning_details":[{"type":"reasoning.text","text":"?\" (","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"used as","reasoning_details":[{"type":"reasoning.text","text":"used as","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a greeting","reasoning_details":[{"type":"reasoning.text","text":" a greeting","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":").\n ","reasoning_details":[{"type":"reasoning.text","text":").\n ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" * ","reasoning_details":[{"type":"reasoning.text","text":" * ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *Add","reasoning_details":[{"type":"reasoning.text","text":" *Add","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the time","reasoning_details":[{"type":"reasoning.text","text":" the time","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"-of-day","reasoning_details":[{"type":"reasoning.text","text":"-of-day","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" greetings.*\n","reasoning_details":[{"type":"reasoning.text","text":" greetings.*\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *","reasoning_details":[{"type":"reasoning.text","text":" *","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **","reasoning_details":[{"type":"reasoning.text","text":" **","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Bom","reasoning_details":[{"type":"reasoning.text","text":"Bom","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" dia**","reasoning_details":[{"type":"reasoning.text","text":" dia**","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" (bo","reasoning_details":[{"type":"reasoning.text","text":" (bo","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"hn","reasoning_details":[{"type":"reasoning.text","text":"hn","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" DEE-","reasoning_details":[{"type":"reasoning.text","text":" DEE-","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ah) -","reasoning_details":[{"type":"reasoning.text","text":"ah) -","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Good morning","reasoning_details":[{"type":"reasoning.text","text":" Good morning","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\n ","reasoning_details":[{"type":"reasoning.text","text":"\n ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" * ","reasoning_details":[{"type":"reasoning.text","text":" * ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **Bo","reasoning_details":[{"type":"reasoning.text","text":" **Bo","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"a tarde","reasoning_details":[{"type":"reasoning.text","text":"a tarde","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"** (","reasoning_details":[{"type":"reasoning.text","text":"** (","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"boh","reasoning_details":[{"type":"reasoning.text","text":"boh","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"-","reasoning_details":[{"type":"reasoning.text","text":"-","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ah","reasoning_details":[{"type":"reasoning.text","text":"ah","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" TAR-d","reasoning_details":[{"type":"reasoning.text","text":" TAR-d","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"jee)","reasoning_details":[{"type":"reasoning.text","text":"jee)","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" - Good","reasoning_details":[{"type":"reasoning.text","text":" - Good","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" afternoon\n","reasoning_details":[{"type":"reasoning.text","text":" afternoon\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *","reasoning_details":[{"type":"reasoning.text","text":" *","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" **","reasoning_details":[{"type":"reasoning.text","text":" **","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Boa noite","reasoning_details":[{"type":"reasoning.text","text":"Boa noite","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"** (","reasoning_details":[{"type":"reasoning.text","text":"** (","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"boh","reasoning_details":[{"type":"reasoning.text","text":"boh","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"-ah","reasoning_details":[{"type":"reasoning.text","text":"-ah","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" NOY","reasoning_details":[{"type":"reasoning.text","text":" NOY","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"-tche","reasoning_details":[{"type":"reasoning.text","text":"-tche","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"e) -","reasoning_details":[{"type":"reasoning.text","text":"e) -","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Good evening","reasoning_details":[{"type":"reasoning.text","text":" Good evening","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" / Good","reasoning_details":[{"type":"reasoning.text","text":" / Good","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" night\n","reasoning_details":[{"type":"reasoning.text","text":" night\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *","reasoning_details":[{"type":"reasoning.text","text":" *","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *","reasoning_details":[{"type":"reasoning.text","text":" *","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Add a","reasoning_details":[{"type":"reasoning.text","text":"Add a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" concluding sentence","reasoning_details":[{"type":"reasoning.text","text":" concluding sentence","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".* \"","reasoning_details":[{"type":"reasoning.text","text":".* \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"For","reasoning_details":[{"type":"reasoning.text","text":"For","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a simple","reasoning_details":[{"type":"reasoning.text","text":" a simple","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" '","reasoning_details":[{"type":"reasoning.text","text":" '","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"hi',","reasoning_details":[{"type":"reasoning.text","text":"hi',","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" '","reasoning_details":[{"type":"reasoning.text","text":" '","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Oi!'","reasoning_details":[{"type":"reasoning.text","text":"Oi!'","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" is your","reasoning_details":[{"type":"reasoning.text","text":" is your","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" best bet","reasoning_details":[{"type":"reasoning.text","text":" best bet","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" You","reasoning_details":[{"type":"reasoning.text","text":" You","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" can't","reasoning_details":[{"type":"reasoning.text","text":" can't","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" go wrong","reasoning_details":[{"type":"reasoning.text","text":" go wrong","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" with it","reasoning_details":[{"type":"reasoning.text","text":" with it","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"!\"\n","reasoning_details":[{"type":"reasoning.text","text":"!\"\n","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *","reasoning_details":[{"type":"reasoning.text","text":" *","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" *","reasoning_details":[{"type":"reasoning.text","text":" *","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Review and","reasoning_details":[{"type":"reasoning.text","text":"Review and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Refine","reasoning_details":[{"type":"reasoning.text","text":" Refine","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":":* Read","reasoning_details":[{"type":"reasoning.text","text":":* Read","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" through the","reasoning_details":[{"type":"reasoning.text","text":" through the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" drafted response","reasoning_details":[{"type":"reasoning.text","text":" drafted response","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":". Is","reasoning_details":[{"type":"reasoning.text","text":". Is","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" it clear","reasoning_details":[{"type":"reasoning.text","text":" it clear","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"? Is","reasoning_details":[{"type":"reasoning.text","text":"? Is","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the pronunciation","reasoning_details":[{"type":"reasoning.text","text":" the pronunciation","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" guide helpful","reasoning_details":[{"type":"reasoning.text","text":" guide helpful","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"? (","reasoning_details":[{"type":"reasoning.text","text":"? (","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"I","reasoning_details":[{"type":"reasoning.text","text":"I","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"'ll add","reasoning_details":[{"type":"reasoning.text","text":"'ll add","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" simple","reasoning_details":[{"type":"reasoning.text","text":" simple","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" phonetic","reasoning_details":[{"type":"reasoning.text","text":" phonetic","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" spell","reasoning_details":[{"type":"reasoning.text","text":" spell","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ings).","reasoning_details":[{"type":"reasoning.text","text":"ings).","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Is the","reasoning_details":[{"type":"reasoning.text","text":" Is the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" tone friendly","reasoning_details":[{"type":"reasoning.text","text":" tone friendly","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and helpful","reasoning_details":[{"type":"reasoning.text","text":" and helpful","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"? Yes","reasoning_details":[{"type":"reasoning.text","text":"? Yes","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":", this","reasoning_details":[{"type":"reasoning.text","text":", this","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" looks good","reasoning_details":[{"type":"reasoning.text","text":" looks good","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":". It","reasoning_details":[{"type":"reasoning.text","text":". It","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"'s comprehensive","reasoning_details":[{"type":"reasoning.text","text":"'s comprehensive","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" but starts","reasoning_details":[{"type":"reasoning.text","text":" but starts","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" with the","reasoning_details":[{"type":"reasoning.text","text":" with the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" simplest,","reasoning_details":[{"type":"reasoning.text","text":" simplest,","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" most direct","reasoning_details":[{"type":"reasoning.text","text":" most direct","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" answer.","reasoning_details":[{"type":"reasoning.text","text":" answer.","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"Oi!\n\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"That's","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" the most","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" common and","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" informal way","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" to say","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" \"hi","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"\" in","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" Portuguese,","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" especially in","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" Brazil.\n\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"Here","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" are a","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" few other","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" options,","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" from","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" most to","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" least formal","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":":\n\n*","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" **","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"OlĆ”","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"** (","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"oh-L","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"AH)","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" - This","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" is the","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" standard","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" \"hello","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"\"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" and is","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" universally understood","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":". It","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"'s a","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" safe","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" and","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" polite","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" choice for","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" any situation","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":".\n*","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" **","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"E a","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"Ć?","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"** (","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"eh ah","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"-EE","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":") -","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" This is","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" a very","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" informal","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" \"What","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"'s up?\"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" used","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" between","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" friends.\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"* ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" **T","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"udo bem?","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"** (","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"TOO","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"-doo","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" beng)","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" - Liter","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"ally \"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"All good","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"?\", but","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" it's","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" used just","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" like \"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"How are","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" you?\" as","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" a common","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" greeting.\n\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"You can","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" also use","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" time","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"-of-day","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" greetings:\n\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"* ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" **B","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"om dia**","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" (bo","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"hn DE","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"E-","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"ah) -","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" Good morning","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n*","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" **","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"Boa tarde","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"** (","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"boh","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"-ah","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" TAR-d","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"jee)","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" - Good","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" afternoon\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"* ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" **Bo","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"a noite","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"** (","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"boh","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"-ah","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" NOY","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"-tche","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"e)","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" - Good","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" evening /","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" Good night","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n\nFor","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" a simple","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":",","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" friendly \"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"hi,\"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" just","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" go","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":" with **","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"Oi","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"!**","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1761053335-cdlosZidwxAsuNA4lZIc","provider":"GMICloud","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053335,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":16,"completion_tokens":1261,"total_tokens":1277,"cost":0.0025316,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000096,"upstream_inference_completions_cost":0.002522},"completion_tokens_details":{"reasoning_tokens":1031,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 898.68ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/tool.yaml
new file mode 100644
index 000000000..3563c59b3
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 479
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"z-ai/glm-4.6","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n{\"id\":\"gen-1761053349-ax5pHFoyZLofGHsE7sE3\",\"provider\":\"BaseTen\",\"model\":\"z-ai/glm-4.6\",\"object\":\"chat.completion\",\"created\":1761053349,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\\nI'll get the weather information for Florence, Italy for you.\\n\",\"refusal\":null,\"reasoning\":\"The user is asking for weather information for Florence, Italy. I have access to a weather function that can get weather information for a location. The function requires a \\\"location\\\" parameter, and the user has provided \\\"Florence, Italy\\\" as the location. I should use this exact location string.\",\"tool_calls\":[{\"index\":0,\"id\":\"chatcmpl-tool-71e392d95a264283ac9c107c8bfb4fa1\",\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\": \\\"Florence,Italy\\\"}\"}}]}}],\"system_fingerprint\":null,\"usage\":{\"prompt_tokens\":187,\"completion_tokens\":92,\"total_tokens\":279,\"cost\":0.0003146,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0001122,\"upstream_inference_completions_cost\":0.0002024},\"completion_tokens_details\":{\"reasoning_tokens\":74,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 482.884625ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 843
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"\nI''ll get the weather information for Florence, Italy for you.\n","tool_calls":[{"id":"chatcmpl-tool-71e392d95a264283ac9c107c8bfb4fa1","function":{"arguments":"{\"location\": \"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"chatcmpl-tool-71e392d95a264283ac9c107c8bfb4fa1","role":"tool"}],"model":"z-ai/glm-4.6","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761053351-jOaT5elsnmNlkQPC7t2C\",\"provider\":\"Mancer 2\",\"model\":\"z-ai/glm-4.6\",\"object\":\"chat.completion\",\"created\":1761053351,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\\n\\nThe weather in Florence, Italy is currently 40°C (104°F). That's quite hot! Make sure to stay hydrated and seek shade if you're out and about.\",\"refusal\":null,\"reasoning\":\"The weather function returned \\\"40 C\\\" for Florence, Italy. This appears to be the temperature in Celsius. 40°C is quite hot - that's 104°F. I should provide this information to the user in a clear and helpful way.\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"The weather function returned \\\"40 C\\\" for Florence, Italy. This appears to be the temperature in Celsius. 40°C is quite hot - that's 104°F. I should provide this information to the user in a clear and helpful way.\",\"format\":\"unknown\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":229,\"completion_tokens\":90,\"total_tokens\":319,\"cost\":0.000305,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00012595,\"upstream_inference_completions_cost\":0.00018},\"completion_tokens_details\":{\"reasoning_tokens\":55,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 533.107209ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/tool_streaming.yaml
new file mode 100644
index 000000000..fea17226a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/glm-4.6/tool_streaming.yaml
@@ -0,0 +1,301 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 533
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"z-ai/glm-4.6","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"The","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user is","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" asking for","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather information","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for Florence","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":", Italy","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":". I","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" have access","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to a","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather function","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" that takes","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a location","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" parameter.","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" The user","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" has","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" provided \"","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Florence","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",Italy","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\" as","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the location","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":". I","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" should use","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" this exact","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" value","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for the","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" location parameter","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"I","reasoning":"","reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":"'ll get","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":" the weather","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":" information for","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":" Florence,","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":" Italy for","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":" you.\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"chatcmpl-tool-bcdb2f683eff40b2b75cf69a8d7af3f9","type":"function","function":{"name":"weather","arguments":"{\"location\": \"Florence,Italy\"}"}}]},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1761053354-0U4NE69ev42zmjB8DnYp","provider":"BaseTen","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053354,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":187,"completion_tokens":82,"total_tokens":269,"cost":0.0002926,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0001122,"upstream_inference_completions_cost":0.0001804},"completion_tokens_details":{"reasoning_tokens":62,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 379.787791ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 897
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"\nI''ll get the weather information for Florence, Italy for you.\n","tool_calls":[{"id":"chatcmpl-tool-bcdb2f683eff40b2b75cf69a8d7af3f9","function":{"arguments":"{\"location\": \"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"chatcmpl-tool-bcdb2f683eff40b2b75cf69a8d7af3f9","role":"tool"}],"model":"z-ai/glm-4.6","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"The","reasoning_details":[{"type":"reasoning.text","text":"The","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.text","text":" weather","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" function","reasoning_details":[{"type":"reasoning.text","text":" function","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" returned","reasoning_details":[{"type":"reasoning.text","text":" returned","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.text","text":" a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" result","reasoning_details":[{"type":"reasoning.text","text":" result","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" of","reasoning_details":[{"type":"reasoning.text","text":" of","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.text","text":" \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"40","reasoning_details":[{"type":"reasoning.text","text":"40","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" C","reasoning_details":[{"type":"reasoning.text","text":" C","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\"","reasoning_details":[{"type":"reasoning.text","text":"\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.text","text":" for","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.text","text":" Florence","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.text","text":",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Italy","reasoning_details":[{"type":"reasoning.text","text":" Italy","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" This","reasoning_details":[{"type":"reasoning.text","text":" This","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" is","reasoning_details":[{"type":"reasoning.text","text":" is","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" quite","reasoning_details":[{"type":"reasoning.text","text":" quite","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" hot","reasoning_details":[{"type":"reasoning.text","text":" hot","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" -","reasoning_details":[{"type":"reasoning.text","text":" -","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.text","text":" ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"40","reasoning_details":[{"type":"reasoning.text","text":"40","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" degrees","reasoning_details":[{"type":"reasoning.text","text":" degrees","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Celsius","reasoning_details":[{"type":"reasoning.text","text":" Celsius","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.text","text":" I","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" should","reasoning_details":[{"type":"reasoning.text","text":" should","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" provide","reasoning_details":[{"type":"reasoning.text","text":" provide","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" this","reasoning_details":[{"type":"reasoning.text","text":" this","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" information","reasoning_details":[{"type":"reasoning.text","text":" information","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.text","text":" to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.text","text":" user","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" in","reasoning_details":[{"type":"reasoning.text","text":" in","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.text","text":" a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" clear","reasoning_details":[{"type":"reasoning.text","text":" clear","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.text","text":" and","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" helpful","reasoning_details":[{"type":"reasoning.text","text":" helpful","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" way","reasoning_details":[{"type":"reasoning.text","text":" way","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"The","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" current","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" weather","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" in","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" Florence","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":",","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" Italy","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" is","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"40","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"°C","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" (","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"104","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"°F","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":").","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" That","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"'s","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" quite","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" hot","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"!","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" Make","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" sure","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" to","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" stay","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" hydrated","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" and","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" seek","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" shade","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" if","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" you","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"'re","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" out","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" and","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":" about","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":".","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1761053355-0YaA5n5ayn7ILdkjK5hC","provider":"Mancer 2","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761053355,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":229,"completion_tokens":81,"total_tokens":310,"cost":0.0002875,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00012595,"upstream_inference_completions_cost":0.000162},"completion_tokens_details":{"reasoning_tokens":46,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 394.828458ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/multi_tool.yaml
new file mode 100644
index 000000000..d786f5599
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 853
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"openai/gpt-5","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054256-qNjLnEZH5TGQX6wRWdm5\",\"provider\":\"OpenAI\",\"model\":\"openai/gpt-5\",\"object\":\"chat.completion\",\"created\":1761054256,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"completed\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":\"**Preparing to present results**\\n\\nIām thinking we should present the results once the tool responds. Usually, theyāll come back fine, so we can focus on producing the outputs. I want to keep formatting light, maybe allowing bullet lists but staying concise overall. The user is specifically interested in the sum and product, so I need to make sure we extract that information clearly. Letās get ready to call the parallel tool for this!\",\"tool_calls\":[{\"id\":\"call_nfjtVc7votxNeL9vtmslg8fI\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"add\",\"arguments\":\"{\\\"a\\\":2,\\\"b\\\":3}\"}},{\"id\":\"call_NnAs1Vwlp5n0aRXy7qPUiuUO\",\"index\":1,\"type\":\"function\",\"function\":{\"name\":\"multiply\",\"arguments\":\"{\\\"a\\\":2,\\\"b\\\":3}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"**Preparing to present results**\\n\\nIām thinking we should present the results once the tool responds. Usually, theyāll come back fine, so we can focus on producing the outputs. I want to keep formatting light, maybe allowing bullet lists but staying concise overall. The user is specifically interested in the sum and product, so I need to make sure we extract that information clearly. Letās get ready to call the parallel tool for this!\",\"format\":\"openai-responses-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"gAAAAABo9443EZrFJ8d7iSNnTSGApMH69Swn59Payx4rS-LHMK3GbL7fVGTfAE3qqy5ArAV0YW4FW6LWv4kyK6euhCk8_D7ttOcWuGAO0QmbLfxAmfO2T-dQc_zKwr1P6MsRyVmoagCUNbkXcNWeJX-vgRBtqrzW32zUw5axDrF0y-h5Y6r2vkHt-FkRtCdwCJ5juwZnzkQLOdp4FofMWMlsJiMl0g1mnmsDymtKOLZ4cUugWauiwgpkUlRis0Ro70bVObA1MwYofIs0XaTCRA5Ztp-SO6J9neqel-nydRH5-D6WKpIpLiuE2oUCAdMLYUKkUcnHm3Q428wwqbUzoSfTxwGFg3JXzY8_wBPLLrJSTYzXTsxLOKXLBTFe6XfCzt8bnBTMD65hJOSxfA4N1zbJ8n_uG8Unb8Xt9OwTpqhOvSrLnVriqMg1pP9TjCJxBf0NXweWkdmG9WjnL2scnqsQjLOdclhBmESWScCqQpx0KB5ZKPYx_6yNsIGhl1Fxrxcj-1aNhgSnAeIGE05ZM6lVMYs0BV6aa_C_ZeVl_MyRguMp_6ilaG05VqxTYpGqSnbwlLkpG48_zOQAVtFxkD3Rb9CJJJIuORiGiTV1JBGR8S-vMStfTy-1f6vvfJjahAmJ7PiHfBJ9a8a3DMIiZaygOXnPrr_duMlk3FKdOX_N-7PByXwDfz6TS4sGsTnzQ3D1Q6hFpCq3wdzBlUPio1JRvRNLWp2VNGfrJp4tXsBUlsvVXR7kYsxRPsZdzA6RQzT2azx5OwIw6VGiCBwJmaNzq1DpvxlevjM_PgCDFkurTMNR6ip_CSEEgyFJBGwZ-UA56DimJZxZIPCiAQglMSc9HrPyHtREiVcJm6EYyA8hbtCYYbo59jJZwVO8uAJ4S9Ko8WgKy12YdFwoUzUSpc9m7ejvV-IjvZpeeEnKVEXpZQ6MWdx8HIpW708yi2qcY1E4P72anaXUzCkI5ycHjktiNV9A3pfMc6CmaQO-0tWiSjQNvHv0UG8DKGU8BVd_8kW9X7oouXJVZcGuNLeZA1GLwuUJgdT27yl93gd9VsjwLKHXmnTKsuj0CN_GwlXKtoLfCwvdud42U7ZVGij7pQDDEHUiHXw09zOx7r6tyHyT1zGCK-A2O_qeBq6G3FqgIevbD3IG4mhhs87R2SEkWjWK_6xI-bj8ILvKIaGR2Yo4QQZ_Dl_eW8bKpa6jV8DEY5OdRF4O6UmOS4YXcJ9imoVFQ-EZgkS1A-DTD-aYfjh07__H429Z9ISFMZXhA28NjPgQ1FkhTxUAtGgQW1uOWX7TxGzmAKlOxC1Xh4LliAtQhFTGuN-NGSYlIEpk9cAtmx96kHjN1PaoA0EE9JePuOJvA986qwwcg7_Twoj_WiXHrKvtXuq1WPYRzwr2whun70g4tlmxvZUeBiizg6GClzyhaeSBsDYdY239MyfH11QPIY7jJQP5VjuQSWrog09dZ-0fjoA2kVHfswgRY3PYNykni3v9eULwSN7cU-Y6o89lsJursd1oaUzqnVEVanwKaeFMFboyY-GPG5qsYpHelbqOgoM2iX4PacsVrhwNDESO_NgxrIA9LKL0k-x32JXLEg_SWvWP2HqQPOALoBdpjL5QbvDOOdHRj1hSiZpNhZP9QkUq2qY99ia_AbGcUC4cPXz0RzNfuGg8tdNrJMQQem-4aNSsiRFRW4NJGNqTCjH52AgAd5fU8eS-CRc6YVIOah0_LpscMXyouRrr0Yf3uyjnQx0IVZ-W7A8kNg6ankc3ipqjar02eFEG0thBRjkzyDQZXDUAFSBKxkzRtdhgtAkLz2HgdGg46207M7aed6BmZBWDbAnRLZmHbfIki4lqeU8bhO4bFy8WoeZpCcGfSIIuQl3y0dx3L6OCskhP5i5NK-kffLyGdQTZJv4pjSHDl3SmSNr_k-txP4b8Kf9s2QieVsCpbA12iXC21i9nTxWRlu9JTvDgq-Ss4QVjEXClKkAI26OgwmamAGODhejWJp_sOFWihc5cpQ0qbp-K_59k7VODgOU97ncdjb9yCA8GJccewcsfefwr1NDid4sW1G1wOLCJNOHIvYWLoAT3u-iX6hjAK7nzVPqIMM9X3iXG_ksXQiVuZ4Q7tADi9EGFfLpRoXyQ2ncPsXaJznJ6AiWNfYHy0ROwgn5GTbVa2jBflaAhwLUbYe1zyILp71jxY72wRMEuxbKoGpzHqdZiFR6V0WqVHR80DdWULM9_Q0wBOjUuFiWEIpcka9nTuLmiTOGnGhh1p5Gucyf6p16etqbzfg7ONOPtuwv0k-Bm2ZIfPpV65PDmmwCw74P_CwAydzOSE9n_SSW7ZBDtvDEH-QTYIvu185kIeGkJDLkz-P3evhLu7v9oJd4HHc4N7Nsi6pBSzyOuvUxCkDvonjSipK1C4zSS197fmiTbm1QWGNBX5vPm3FhFPgIcnZ8un4iw8Bcs6K00hxvt68tQmWzlqSLB3xz-PmRgxBA-FuEzktIBZ2E8F2X2ZPngua7X7A96WuqHUh_usG7ELeqv2VmXC2id1AXMSMzXkDU=\",\"id\":\"rs_059ba3bb134ec3cc0168f78e31f7a481938a88f8e8343ed302\",\"format\":\"openai-responses-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":58,\"completion_tokens\":312,\"total_tokens\":370,\"cost\":0.0031925,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000725,\"upstream_inference_completions_cost\":0.00312},\"completion_tokens_details\":{\"reasoning_tokens\":256,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 830.848ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 4523
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_nfjtVc7votxNeL9vtmslg8fI","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"call_NnAs1Vwlp5n0aRXy7qPUiuUO","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"openai-responses-v1","index":0,"summary":"**Preparing to present results**\n\nIām thinking we should present the results once the tool responds. Usually, theyāll come back fine, so we can focus on producing the outputs. I want to keep formatting light, maybe allowing bullet lists but staying concise overall. The user is specifically interested in the sum and product, so I need to make sure we extract that information clearly. Letās get ready to call the parallel tool for this!","type":"reasoning.summary"},{"data":"gAAAAABo9443EZrFJ8d7iSNnTSGApMH69Swn59Payx4rS-LHMK3GbL7fVGTfAE3qqy5ArAV0YW4FW6LWv4kyK6euhCk8_D7ttOcWuGAO0QmbLfxAmfO2T-dQc_zKwr1P6MsRyVmoagCUNbkXcNWeJX-vgRBtqrzW32zUw5axDrF0y-h5Y6r2vkHt-FkRtCdwCJ5juwZnzkQLOdp4FofMWMlsJiMl0g1mnmsDymtKOLZ4cUugWauiwgpkUlRis0Ro70bVObA1MwYofIs0XaTCRA5Ztp-SO6J9neqel-nydRH5-D6WKpIpLiuE2oUCAdMLYUKkUcnHm3Q428wwqbUzoSfTxwGFg3JXzY8_wBPLLrJSTYzXTsxLOKXLBTFe6XfCzt8bnBTMD65hJOSxfA4N1zbJ8n_uG8Unb8Xt9OwTpqhOvSrLnVriqMg1pP9TjCJxBf0NXweWkdmG9WjnL2scnqsQjLOdclhBmESWScCqQpx0KB5ZKPYx_6yNsIGhl1Fxrxcj-1aNhgSnAeIGE05ZM6lVMYs0BV6aa_C_ZeVl_MyRguMp_6ilaG05VqxTYpGqSnbwlLkpG48_zOQAVtFxkD3Rb9CJJJIuORiGiTV1JBGR8S-vMStfTy-1f6vvfJjahAmJ7PiHfBJ9a8a3DMIiZaygOXnPrr_duMlk3FKdOX_N-7PByXwDfz6TS4sGsTnzQ3D1Q6hFpCq3wdzBlUPio1JRvRNLWp2VNGfrJp4tXsBUlsvVXR7kYsxRPsZdzA6RQzT2azx5OwIw6VGiCBwJmaNzq1DpvxlevjM_PgCDFkurTMNR6ip_CSEEgyFJBGwZ-UA56DimJZxZIPCiAQglMSc9HrPyHtREiVcJm6EYyA8hbtCYYbo59jJZwVO8uAJ4S9Ko8WgKy12YdFwoUzUSpc9m7ejvV-IjvZpeeEnKVEXpZQ6MWdx8HIpW708yi2qcY1E4P72anaXUzCkI5ycHjktiNV9A3pfMc6CmaQO-0tWiSjQNvHv0UG8DKGU8BVd_8kW9X7oouXJVZcGuNLeZA1GLwuUJgdT27yl93gd9VsjwLKHXmnTKsuj0CN_GwlXKtoLfCwvdud42U7ZVGij7pQDDEHUiHXw09zOx7r6tyHyT1zGCK-A2O_qeBq6G3FqgIevbD3IG4mhhs87R2SEkWjWK_6xI-bj8ILvKIaGR2Yo4QQZ_Dl_eW8bKpa6jV8DEY5OdRF4O6UmOS4YXcJ9imoVFQ-EZgkS1A-DTD-aYfjh07__H429Z9ISFMZXhA28NjPgQ1FkhTxUAtGgQW1uOWX7TxGzmAKlOxC1Xh4LliAtQhFTGuN-NGSYlIEpk9cAtmx96kHjN1PaoA0EE9JePuOJvA986qwwcg7_Twoj_WiXHrKvtXuq1WPYRzwr2whun70g4tlmxvZUeBiizg6GClzyhaeSBsDYdY239MyfH11QPIY7jJQP5VjuQSWrog09dZ-0fjoA2kVHfswgRY3PYNykni3v9eULwSN7cU-Y6o89lsJursd1oaUzqnVEVanwKaeFMFboyY-GPG5qsYpHelbqOgoM2iX4PacsVrhwNDESO_NgxrIA9LKL0k-x32JXLEg_SWvWP2HqQPOALoBdpjL5QbvDOOdHRj1hSiZpNhZP9QkUq2qY99ia_AbGcUC4cPXz0RzNfuGg8tdNrJMQQem-4aNSsiRFRW4NJGNqTCjH52AgAd5fU8eS-CRc6YVIOah0_LpscMXyouRrr0Yf3uyjnQx0IVZ-W7A8kNg6ankc3ipqjar02eFEG0thBRjkzyDQZXDUAFSBKxkzRtdhgtAkLz2HgdGg46207M7aed6BmZBWDbAnRLZmHbfIki4lqeU8bhO4bFy8WoeZpCcGfSIIuQl3y0dx3L6OCskhP5i5NK-kffLyGdQTZJv4pjSHDl3SmSNr_k-txP4b8Kf9s2QieVsCpbA12iXC21i9nTxWRlu9JTvDgq-Ss4QVjEXClKkAI26OgwmamAGODhejWJp_sOFWihc5cpQ0qbp-K_59k7VODgOU97ncdjb9yCA8GJccewcsfefwr1NDid4sW1G1wOLCJNOHIvYWLoAT3u-iX6hjAK7nzVPqIMM9X3iXG_ksXQiVuZ4Q7tADi9EGFfLpRoXyQ2ncPsXaJznJ6AiWNfYHy0ROwgn5GTbVa2jBflaAhwLUbYe1zyILp71jxY72wRMEuxbKoGpzHqdZiFR6V0WqVHR80DdWULM9_Q0wBOjUuFiWEIpcka9nTuLmiTOGnGhh1p5Gucyf6p16etqbzfg7ONOPtuwv0k-Bm2ZIfPpV65PDmmwCw74P_CwAydzOSE9n_SSW7ZBDtvDEH-QTYIvu185kIeGkJDLkz-P3evhLu7v9oJd4HHc4N7Nsi6pBSzyOuvUxCkDvonjSipK1C4zSS197fmiTbm1QWGNBX5vPm3FhFPgIcnZ8un4iw8Bcs6K00hxvt68tQmWzlqSLB3xz-PmRgxBA-FuEzktIBZ2E8F2X2ZPngua7X7A96WuqHUh_usG7ELeqv2VmXC2id1AXMSMzXkDU=","format":"openai-responses-v1","id":"rs_059ba3bb134ec3cc0168f78e31f7a481938a88f8e8343ed302","index":0,"type":"reasoning.encrypted"}]},{"content":"5","tool_call_id":"call_nfjtVc7votxNeL9vtmslg8fI","role":"tool"},{"content":"6","tool_call_id":"call_NnAs1Vwlp5n0aRXy7qPUiuUO","role":"tool"}],"model":"openai/gpt-5","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n{\"id\":\"gen-1761054264-Y4ejQT0Sw5FGzgJjsWWy\",\"provider\":\"OpenAI\",\"model\":\"openai/gpt-5\",\"object\":\"chat.completion\",\"created\":1761054264,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"completed\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"- Sum (2 + 3) = 5\\n- Product (2 Ć 3) = 6\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":442,\"completion_tokens\":27,\"total_tokens\":469,\"cost\":0.0008225,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0005525,\"upstream_inference_completions_cost\":0.00027},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 568.905458ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/multi_tool_streaming.yaml
new file mode 100644
index 000000000..62259c167
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/multi_tool_streaming.yaml
@@ -0,0 +1,129 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 890
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"openai/gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.encrypted","data":"gAAAAABo95AdNmqxM6HBeqh0dzQ-aNcv5qbGNYIt678-GeFu7z78caXKNcqwLKF1Dv9QhgL3kXBe-TWZ8l0pfCMr353vKhrLLj6SmwVm4uhKbEsNgwx0yGH6mn8fMmpftY29Sm-LiEIujKW_7NVZWSsCtLJYVDW8iS3r1j_LDDJqU6z6xKanbssHCfQeffAaxN2iTuADLUsqhTvNDJqWa6fNOrB2tzIxV3-iksbWPgss1czhUeljdLxUmapXaOcatf2K2RX2ZNWYPscs-XZBdTefLQ8aIn90i7kE2yf6V73sLcBpzy4JGxxrGQtPTc3zMTG7kXjO7xOAWjbiN__jQlcy57r5S7fVJ6hPtp5ow-KMjQ3Uhi98v8onA4wbDqZmmxji1sK4tJUn4ZB_1II-waOGaHFEWuUWbKKzv_dqbaE7wOs84410yD9o1NXJTPle4J29vwykRIrz--IKHL2cD4F4V0ZclWDIn_-hvauAeYDHZ7wrloTsIRDGdk74Z-DSCVd62XCdIgWdr-N7Vjx4CkyPS6aHwft99MZu9ZY0B0nD-I7DNwRcVFHjRtWYvS1snAeytWTVxmJguCMq90CYqwqj7BYu4v58Kx9xasJUlrdmRLuIWQ1DEHvAjWqLlRhBLA23Q-bUPwxvcVxRFdh30MaF66ZwZli6jo11LW3-NF7sQwDc3SptwdWuSFCVtBbTDYUwWHT2u0H4RWbqR8Yyhrm4ZiPYASQpBpELvomgSjyTD0qLeImvJ_PlRof5I9mBk1_DQcJABic8wndURR9c1visgJrBvdDSyhyOF5Y-spFH4N1q4PLMu7wjZOe9KrY115mPF3hnfXfw6K3FHqDxUx58VJjHtTxevIOCrun2mziervO3xOuqYDE21Qe1tSeaUpLTHynPVjSDgGpqcQrnUd35B_ggR-T8QBnf3kVYFxetQjpHxlehdR5jpNd6CWtXuiIgtoB5AQEKp4ysnm0u_fA16-wPAErwtSZ21Hjg65LtdSl8H2_qHQXTey3sHOi_wYrw5YISLci840Noaq6Hwj0sWRhVvu_e2cvM2gjR1tNJ51KHL7dMJplpOCbqdesOYCRMYE-LJtj_aqffFr2RDxJTXHrI_53poZbM6vNxINQ1f75F7c70R6zR3kLgAOE5Jd99pZMDwZoYVCdVPoHyPL3kVunWJRHIY3dQj4nx1gDaXzm_C2rIJG8UOcHSRoz3Y_7pJTvVmYlAC4RyzGEFAVv8VbBPoYKHK5hPt4mfLM4UdI2iaio5MQTqoGzIEHhLTHcj3Ic3Foy17_BPFiBIEjy6UMinU4SjCy77-GVhg3hRXhAn7sJOv4gMRH9z53T_yc6zhVXClpi0EyK7cWqNK2YYksQJ0zj6VqFnvAxDRDS2-6gjNxYGQ3Pzu72ldKtG_vsFHG8lTOCcr4XB1gVkMphxxWP8IUu4WjmfUrALolo1tN22AxQkloIL2eLsCFCBKIFCWCU5jd4TnzdK0mTQk1fUMxdGgrqeVfqfoYLuhEbk-mbAneAwUma9IY6FIdq_2nN6DEr3drMT1_9Q98otTgInkFYjIdzzlS3gtQdjr0Ql81Zi5uybafAIhiqvIUekTjmZpnI5mIjvSE1FDaaToBMYNOU0tW3LbcP66_fYMMBNX3UvdbSNdMXBpbD2BgDhkSJK0KMGOLBYjfPbUCi88Ef2H3C9l-r51YKhy5Tc_VLuuwtnfd4B7LDj0DM2eXRh120UiEfcjSYJH5h34nhlc9Oup8kcJaEgwVovbBUIVM-Z_nTMB936faBdVZHKFbtkGIKl30BV12X5j1eFZgOcDugkCnF50UY2jY3WNhC8ChewCjxACp8C4PuCqABPId07XaqrnSyEDg7UzUM7mIDufbghUavDpKK8rqnNcz-kCsKXzyAFrr4l5-2HDetBmUiRxToX5KVeVMv_IFiyQdWeL_MfoG57swdhPJMcEEb_0EfZzx37cipdUin6FH9ELsUDbn0GZKtahx6NuT2L0hZG3vha_afl-BCPyxqP4JsgnBNMTBeDRd7ERok=","id":"rs_051a5b528a0acc690168f7901bbfb881978e5d366d901f11b3","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"call_mUCAklYTU3uGC65pRz7M7UbY","index":0,"type":"function","function":{"name":"add","arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"{"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"\"a"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"\":"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"2,"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"\"b"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"\":"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"3}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"call_y7BeX0S3uY40okx6MWg7dX2y","index":1,"type":"function","function":{"name":"multiply","arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"type":"function","function":{"arguments":"{"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"type":"function","function":{"arguments":"\"a"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"type":"function","function":{"arguments":"\":"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"type":"function","function":{"arguments":"2,"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"type":"function","function":{"arguments":"\"b"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"type":"function","function":{"arguments":"\":"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"type":"function","function":{"arguments":"3}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"tool_calls","native_finish_reason":"completed","logprobs":null}]}
+
+ data: {"id":"gen-1761054747-aRXhxlwVNm3mtTObq3p8","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054747,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":56,"completion_tokens":183,"total_tokens":239,"cost":0.0019,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00007,"upstream_inference_completions_cost":0.00183},"completion_tokens_details":{"reasoning_tokens":128,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 558.96825ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 3520
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_mUCAklYTU3uGC65pRz7M7UbY","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"call_y7BeX0S3uY40okx6MWg7dX2y","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant","reasoning_details":[{"data":"gAAAAABo95AdNmqxM6HBeqh0dzQ-aNcv5qbGNYIt678-GeFu7z78caXKNcqwLKF1Dv9QhgL3kXBe-TWZ8l0pfCMr353vKhrLLj6SmwVm4uhKbEsNgwx0yGH6mn8fMmpftY29Sm-LiEIujKW_7NVZWSsCtLJYVDW8iS3r1j_LDDJqU6z6xKanbssHCfQeffAaxN2iTuADLUsqhTvNDJqWa6fNOrB2tzIxV3-iksbWPgss1czhUeljdLxUmapXaOcatf2K2RX2ZNWYPscs-XZBdTefLQ8aIn90i7kE2yf6V73sLcBpzy4JGxxrGQtPTc3zMTG7kXjO7xOAWjbiN__jQlcy57r5S7fVJ6hPtp5ow-KMjQ3Uhi98v8onA4wbDqZmmxji1sK4tJUn4ZB_1II-waOGaHFEWuUWbKKzv_dqbaE7wOs84410yD9o1NXJTPle4J29vwykRIrz--IKHL2cD4F4V0ZclWDIn_-hvauAeYDHZ7wrloTsIRDGdk74Z-DSCVd62XCdIgWdr-N7Vjx4CkyPS6aHwft99MZu9ZY0B0nD-I7DNwRcVFHjRtWYvS1snAeytWTVxmJguCMq90CYqwqj7BYu4v58Kx9xasJUlrdmRLuIWQ1DEHvAjWqLlRhBLA23Q-bUPwxvcVxRFdh30MaF66ZwZli6jo11LW3-NF7sQwDc3SptwdWuSFCVtBbTDYUwWHT2u0H4RWbqR8Yyhrm4ZiPYASQpBpELvomgSjyTD0qLeImvJ_PlRof5I9mBk1_DQcJABic8wndURR9c1visgJrBvdDSyhyOF5Y-spFH4N1q4PLMu7wjZOe9KrY115mPF3hnfXfw6K3FHqDxUx58VJjHtTxevIOCrun2mziervO3xOuqYDE21Qe1tSeaUpLTHynPVjSDgGpqcQrnUd35B_ggR-T8QBnf3kVYFxetQjpHxlehdR5jpNd6CWtXuiIgtoB5AQEKp4ysnm0u_fA16-wPAErwtSZ21Hjg65LtdSl8H2_qHQXTey3sHOi_wYrw5YISLci840Noaq6Hwj0sWRhVvu_e2cvM2gjR1tNJ51KHL7dMJplpOCbqdesOYCRMYE-LJtj_aqffFr2RDxJTXHrI_53poZbM6vNxINQ1f75F7c70R6zR3kLgAOE5Jd99pZMDwZoYVCdVPoHyPL3kVunWJRHIY3dQj4nx1gDaXzm_C2rIJG8UOcHSRoz3Y_7pJTvVmYlAC4RyzGEFAVv8VbBPoYKHK5hPt4mfLM4UdI2iaio5MQTqoGzIEHhLTHcj3Ic3Foy17_BPFiBIEjy6UMinU4SjCy77-GVhg3hRXhAn7sJOv4gMRH9z53T_yc6zhVXClpi0EyK7cWqNK2YYksQJ0zj6VqFnvAxDRDS2-6gjNxYGQ3Pzu72ldKtG_vsFHG8lTOCcr4XB1gVkMphxxWP8IUu4WjmfUrALolo1tN22AxQkloIL2eLsCFCBKIFCWCU5jd4TnzdK0mTQk1fUMxdGgrqeVfqfoYLuhEbk-mbAneAwUma9IY6FIdq_2nN6DEr3drMT1_9Q98otTgInkFYjIdzzlS3gtQdjr0Ql81Zi5uybafAIhiqvIUekTjmZpnI5mIjvSE1FDaaToBMYNOU0tW3LbcP66_fYMMBNX3UvdbSNdMXBpbD2BgDhkSJK0KMGOLBYjfPbUCi88Ef2H3C9l-r51YKhy5Tc_VLuuwtnfd4B7LDj0DM2eXRh120UiEfcjSYJH5h34nhlc9Oup8kcJaEgwVovbBUIVM-Z_nTMB936faBdVZHKFbtkGIKl30BV12X5j1eFZgOcDugkCnF50UY2jY3WNhC8ChewCjxACp8C4PuCqABPId07XaqrnSyEDg7UzUM7mIDufbghUavDpKK8rqnNcz-kCsKXzyAFrr4l5-2HDetBmUiRxToX5KVeVMv_IFiyQdWeL_MfoG57swdhPJMcEEb_0EfZzx37cipdUin6FH9ELsUDbn0GZKtahx6NuT2L0hZG3vha_afl-BCPyxqP4JsgnBNMTBeDRd7ERok=","format":"openai-responses-v1","id":"rs_051a5b528a0acc690168f7901bbfb881978e5d366d901f11b3","index":0,"type":"reasoning.encrypted"}]},{"content":"5","tool_call_id":"call_mUCAklYTU3uGC65pRz7M7UbY","role":"tool"},{"content":"6","tool_call_id":"call_y7BeX0S3uY40okx6MWg7dX2y","role":"tool"}],"model":"openai/gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054750-4AMRsUTPcrRnu4eOcH2r","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054750,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054750-4AMRsUTPcrRnu4eOcH2r","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054750,"choices":[{"index":0,"delta":{"role":"assistant","content":"Sum"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054750-4AMRsUTPcrRnu4eOcH2r","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054750,"choices":[{"index":0,"delta":{"role":"assistant","content":":"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054750-4AMRsUTPcrRnu4eOcH2r","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054750,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054750-4AMRsUTPcrRnu4eOcH2r","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054750,"choices":[{"index":0,"delta":{"role":"assistant","content":"5"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054750-4AMRsUTPcrRnu4eOcH2r","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054750,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054750-4AMRsUTPcrRnu4eOcH2r","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054750,"choices":[{"index":0,"delta":{"role":"assistant","content":"Product"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054750-4AMRsUTPcrRnu4eOcH2r","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054750,"choices":[{"index":0,"delta":{"role":"assistant","content":":"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054750-4AMRsUTPcrRnu4eOcH2r","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054750,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054750-4AMRsUTPcrRnu4eOcH2r","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054750,"choices":[{"index":0,"delta":{"role":"assistant","content":"6"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054750-4AMRsUTPcrRnu4eOcH2r","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054750,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"completed","logprobs":null}]}
+
+ data: {"id":"gen-1761054750-4AMRsUTPcrRnu4eOcH2r","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054750,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":355,"completion_tokens":13,"total_tokens":368,"cost":0.00057375,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00044375,"upstream_inference_completions_cost":0.00013},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 738.942209ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/simple.yaml
new file mode 100644
index 000000000..8fe6854c6
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 198
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"openai/gpt-5","max_completion_tokens":4000,"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054225-FM4MnnS8EeJreVmGVKEj\",\"provider\":\"OpenAI\",\"model\":\"openai/gpt-5\",\"object\":\"chat.completion\",\"created\":1761054225,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"completed\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"Oi! (or OlĆ”!)\",\"refusal\":null,\"reasoning\":\"**Providing Portuguese greetings**\\n\\nThe user simply asked me to say hi in Portuguese, so I need to provide that quickly. \\\"OlĆ”\\\" is a great option, but I also think \\\"Oi!\\\" is good for a more informal Brazilian greeting. Since they didn't specify which variant, I'll stick to both. I'll just keep it concise and say: \\\"OlĆ”!\\\" and \\\"Oi!\\\" without any extra formatting or details. No need to overthink it!\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"**Providing Portuguese greetings**\\n\\nThe user simply asked me to say hi in Portuguese, so I need to provide that quickly. \\\"OlĆ”\\\" is a great option, but I also think \\\"Oi!\\\" is good for a more informal Brazilian greeting. Since they didn't specify which variant, I'll stick to both. I'll just keep it concise and say: \\\"OlĆ”!\\\" and \\\"Oi!\\\" without any extra formatting or details. No need to overthink it!\",\"format\":\"openai-responses-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"gAAAAABo944VoAjtPbUJaTTYOF-zjSITgn7ry4YZ2VwmKUKxe-qvTKrrCC5caY3xmbBG4dhiy5ITWJ8T2zXWsVwnR4OQQzZsIovD8GgZgl1KkGj7NcUZPfS11eVr3nPVwT3nv-P6WEYkonYpnLPETjotNT0qX2NxV9YrhiVhtsBJ3ltzQEdfysCabqHlvy2t31nkOj_mj8efxW2fBRyP7ToNaG4kUo5tEn6p-mnxYrqXTaszy8zJcN0hN1CjnoRY-6JfV6mSar-O4-Q45UTkE6zBuMTJFKT8bTWBsPGYd1eldmn7ziZcE_zNHj7h2Ih7zrwv2w5TEWxYrvht28SNFSts0VSBTBikaiUQ-d_3w_qKwsQYTyKXPiPdeKI_9jIP8MFLIPRnbKWNCg3fmxgq_WzPbmMNlNev44JigGvkyO2ANV-pMmtnP8NcArhiJCcpBrZMPDT1A35HVq6ZIdBU1juH_WNDjbwDP-LdrweQ1enycJIk9ik4eUYXC-CaXOuv02wVNQyMt544gc9KN_9XdbuUlM_Q-tRoPIEAP92wPs-rnvW5v-0NqjjO9PcHR414IMcS3JeuVw3OZMxoSgYKViOYv5SYqJU4exwgKJDlyGwFQXp2Faphaft8CTgYpzs4-LAvbnxNdqO4-nAKHPi26EWxBGOffjCk6liFEjnLg2XdRP_lCIwwEtkjfAv_Otq5VLHiY7p0qbIVEC-5ev0VEtHfRKjwHt2N5u3l3C1LuuxRkzocQ29RHMG5z7Y6nST5d3z_8lTEUpC-b_emjCmhbU7dcTyaBddvL5_V2irAVWWKpSsRCFp6JbTa0bjBBAeH6TEnIP8sOF3Fpy01Y30-qNvOhqLo3U75b4HI6PFpVw9iYV4y42_MJ2M942ZkP_Q7ox8N3B2Gu9lAIZx2b4wrTHczwO-BdWVYv9q2eeMg2QmgOLw5ov3aJvnaiZCW40Fl7lLNpq696REn3yx1EoYcUwSTcVSQ6vPWAGLOQ5nW1rThEQ14OvYrpUeFv4KrqiO0Xtx5vO0Ao5GSIa5X49SQJAlQYSIwekU0_iGLwEGd1ry8Wtduy_1wLNuXz2iNrrg5hlrJ2qC47Vv2fs3QhrEPgj1Q3JeEa4U-GNbxakPJE8s0bjxVja-so72cLHayCO7YBAYvsSRJdqHtGf-Aq3SqXiPsWPtvCNCG0ldHINRIO3Rkx5MCDLE2IqrzBzheYtU0MUUFsyN6m_sBRelBKFTvl4168uNq9utOdlMbBuBzdvjElbABQaoDuyM3bHnVMBJAOoMARi1vrKmi_spWtHU7S_31etK-lPZDbWXZrdKsgkEmVD0ucDcMEoR8ypemcA315tpAeNPVl1Tc0K0O3ggVWIhzKmtPMWhmVw4H4Qw-vKS0zzacK77DdBAoXwO4a70cIUh_ItlbTV067hlq4BZji7fX0aXUt2VMbfPOoTX7ccxXPiLFX1Jt_VTmRmjLAfiq-ZqqD0N3duB_DDIWLsGysQzaqRrzH-k6F_5FuEhLANyVb4HWFXI-B3ZsFMNVQWwEOkVEheuuCtjFBCPsrEAhrH1EYpG4hNddCg==\",\"id\":\"rs_0fdd854964fd6c5b0168f78e11988881959023afc34ee76949\",\"format\":\"openai-responses-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":19,\"completion_tokens\":77,\"total_tokens\":96,\"cost\":0.00079375,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00002375,\"upstream_inference_completions_cost\":0.00077},\"completion_tokens_details\":{\"reasoning_tokens\":64,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 525.739417ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/simple_streaming.yaml
new file mode 100644
index 000000000..b814784ff
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/simple_streaming.yaml
@@ -0,0 +1,228 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 252
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"openai/gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"**Respond","reasoning_details":[{"type":"reasoning.summary","summary":"**Respond","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ing","reasoning_details":[{"type":"reasoning.summary","summary":"ing","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" in","reasoning_details":[{"type":"reasoning.summary","summary":" in","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Portuguese","reasoning_details":[{"type":"reasoning.summary","summary":" Portuguese","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"**\n\nThe","reasoning_details":[{"type":"reasoning.summary","summary":"**\n\nThe","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.summary","summary":" user","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" wants","reasoning_details":[{"type":"reasoning.summary","summary":" wants","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" me","reasoning_details":[{"type":"reasoning.summary","summary":" me","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.summary","summary":" to","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" simply","reasoning_details":[{"type":"reasoning.summary","summary":" simply","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" say","reasoning_details":[{"type":"reasoning.summary","summary":" say","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" hi","reasoning_details":[{"type":"reasoning.summary","summary":" hi","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" in","reasoning_details":[{"type":"reasoning.summary","summary":" in","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Portuguese","reasoning_details":[{"type":"reasoning.summary","summary":" Portuguese","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" think","reasoning_details":[{"type":"reasoning.summary","summary":" think","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.summary","summary":" a","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" suitable","reasoning_details":[{"type":"reasoning.summary","summary":" suitable","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" answer","reasoning_details":[{"type":"reasoning.summary","summary":" answer","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" would","reasoning_details":[{"type":"reasoning.summary","summary":" would","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" be","reasoning_details":[{"type":"reasoning.summary","summary":" be","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" either","reasoning_details":[{"type":"reasoning.summary","summary":" either","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.summary","summary":" \"","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Oi","reasoning_details":[{"type":"reasoning.summary","summary":"Oi","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"!\"","reasoning_details":[{"type":"reasoning.summary","summary":"!\"","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" or","reasoning_details":[{"type":"reasoning.summary","summary":" or","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.summary","summary":" \"","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"OlĆ”","reasoning_details":[{"type":"reasoning.summary","summary":"OlĆ”","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"!\"","reasoning_details":[{"type":"reasoning.summary","summary":"!\"","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" because","reasoning_details":[{"type":"reasoning.summary","summary":" because","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" both","reasoning_details":[{"type":"reasoning.summary","summary":" both","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" are","reasoning_details":[{"type":"reasoning.summary","summary":" are","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" common","reasoning_details":[{"type":"reasoning.summary","summary":" common","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" greetings","reasoning_details":[{"type":"reasoning.summary","summary":" greetings","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" There's","reasoning_details":[{"type":"reasoning.summary","summary":" There's","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" really","reasoning_details":[{"type":"reasoning.summary","summary":" really","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" no","reasoning_details":[{"type":"reasoning.summary","summary":" no","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" need","reasoning_details":[{"type":"reasoning.summary","summary":" need","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.summary","summary":" for","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" extra","reasoning_details":[{"type":"reasoning.summary","summary":" extra","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" explanations","reasoning_details":[{"type":"reasoning.summary","summary":" explanations","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" or","reasoning_details":[{"type":"reasoning.summary","summary":" or","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" formatting","reasoning_details":[{"type":"reasoning.summary","summary":" formatting","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":";","reasoning_details":[{"type":"reasoning.summary","summary":";","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" should","reasoning_details":[{"type":"reasoning.summary","summary":" should","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" keep","reasoning_details":[{"type":"reasoning.summary","summary":" keep","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" it","reasoning_details":[{"type":"reasoning.summary","summary":" it","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" concise","reasoning_details":[{"type":"reasoning.summary","summary":" concise","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Since","reasoning_details":[{"type":"reasoning.summary","summary":" Since","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.summary","summary":" \"","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"OlĆ”","reasoning_details":[{"type":"reasoning.summary","summary":"OlĆ”","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"!\"","reasoning_details":[{"type":"reasoning.summary","summary":"!\"","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" seems","reasoning_details":[{"type":"reasoning.summary","summary":" seems","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.summary","summary":" a","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" bit","reasoning_details":[{"type":"reasoning.summary","summary":" bit","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" more","reasoning_details":[{"type":"reasoning.summary","summary":" more","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" formal","reasoning_details":[{"type":"reasoning.summary","summary":" formal","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" might","reasoning_details":[{"type":"reasoning.summary","summary":" might","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" go","reasoning_details":[{"type":"reasoning.summary","summary":" go","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" with","reasoning_details":[{"type":"reasoning.summary","summary":" with","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" that","reasoning_details":[{"type":"reasoning.summary","summary":" that","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Overall","reasoning_details":[{"type":"reasoning.summary","summary":" Overall","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" this","reasoning_details":[{"type":"reasoning.summary","summary":" this","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" task","reasoning_details":[{"type":"reasoning.summary","summary":" task","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" feels","reasoning_details":[{"type":"reasoning.summary","summary":" feels","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" straightforward","reasoning_details":[{"type":"reasoning.summary","summary":" straightforward","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.summary","summary":" and","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" want","reasoning_details":[{"type":"reasoning.summary","summary":" want","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.summary","summary":" to","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" make","reasoning_details":[{"type":"reasoning.summary","summary":" make","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" sure","reasoning_details":[{"type":"reasoning.summary","summary":" sure","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" give","reasoning_details":[{"type":"reasoning.summary","summary":" give","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.summary","summary":" user","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" exactly","reasoning_details":[{"type":"reasoning.summary","summary":" exactly","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" what","reasoning_details":[{"type":"reasoning.summary","summary":" what","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" they","reasoning_details":[{"type":"reasoning.summary","summary":" they","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" asked","reasoning_details":[{"type":"reasoning.summary","summary":" asked","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.summary","summary":" for","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"!","reasoning_details":[{"type":"reasoning.summary","summary":"!","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.encrypted","data":"gAAAAABo944ZreBAMZVOrHbZJiNMgiz8FZUU9DXXFBVRmJKOql95a5lmVEvoRDHb9pXqHh-8xqYrIyyaP9h6wQ-CHFcOxcWcSxbIqX0IKL4drfMsK5lni8uY_GRqCd_B9-95zza8ZrDe4JvEPanw3GTiGbp1SkXylUqpoKzHSVFW3YWmtVCazv6QOlkAd_rzg5CSrKQtrFooCcNTy8x000TyKFLsjRMHajA-8kS0BoReH-5sJOxCqdgStpNiZOawW21-EbAaEuaFF-oIh4H4RinnioyNuvg5kSKQXWP2QbKdWmFl5PWJVa1mHZH0tIlhCOEIpLPIk6yXnOypZpltkuAydRp3dJW1sXyWvcZhNBpAAQwgQLTDYhSTIYUF70yLZ1sKmcG2pLzYGKb1cbLFH0h2P11lu4BrrGpO3c5ZRb9xNbR7HWoTcpTVRqKtFX_pkba2OPFxSqLhGFkn8mcJpKn5qzrMHNgm7hOuAdtgr7bXf3kRoSXsM0-WUCOcxUeTymjLhEERhZK-a-QekdUd63Kn4JRzCQyX25t96OzadnhF0ENKdSOCXlJyYjMvFE2N54L3TjkO-cZYdwriogqRyi8pYXmthXIvesJeFUNpEwOgV9ON9tnZ_mic0Q4gMQI57qj_EfzuxbX1G4nA9YUgViDwJFcoM_-6aVNJJYSAgBgVWRvALpNHCno01gxa-Fl-fyJmW8GEN54dc1zC25j4H2vIZOeR6r4S1RMCQDMXl6U_K_PE2wlmuEIdxgvGQP0jiGQrGeAfzexwLW_khJwF2rcXk8k9rp6VBgr3Bc0Yy6DstK8cDMnU0enquinW4ed15Eo-Z-Z1tXajOoSzMB0eU78NBFOAefuohkJzFHhUhIARKMCuvNGcH6MCI01PfBJPo3n7U5Mfh4FJ7XLfZe3uINIVX5Zs02meQ5fGdvYEihGjb8jWtLb9oENvcrp4-tj-90r2IQNLWn53mR8dykI5BDqdxFw3uG2KxUN8H90zI675hWwp1zMRHBymScpPvb52oBSw-oG0WPl7VVFzBkOrySc88La2V7bL1ulRmW8U_X5PbKIWD-lLQAbbDf631oPuy44nAZCAfwEeyM1y26UmeE5qYBPMxZaZ_bsFlIl5jJw8aJv7ciaVG7Cc0pYV2ynQJ7gCZZeF6ea3XpiYPJtcJKdqKARYe2KV5P_t6pp4cT__Eu51R7-BxETazI55EbFGLD4COtpExWHn3f_T4H4VLLnu17Bh9JdnGw==","id":"rs_0802379db98de7ff0168f78e166a388196bdfcf55851805912","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"OlĆ”"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":"!"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"completed","logprobs":null}]}
+
+ data: {"id":"gen-1761054229-W3eLfNtiq5pKCuUI7w88","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054229,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":19,"completion_tokens":72,"total_tokens":91,"cost":0.00074375,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00002375,"upstream_inference_completions_cost":0.00072},"completion_tokens_details":{"reasoning_tokens":64,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 365.0285ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/tool.yaml
new file mode 100644
index 000000000..c6c819705
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 490
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"openai/gpt-5","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054234-3w7r9GFNyhUJONXBloDl\",\"provider\":\"OpenAI\",\"model\":\"openai/gpt-5\",\"object\":\"chat.completion\",\"created\":1761054234,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"completed\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":\"**Calling weather tool**\\n\\nIām planning to use the weather tool to fetch data for Florence, Italy. We only need one function call, so I donāt really need to use the multi_tool_use.parallel option, which is for calling multiple functions at once. Instead, I'll call functions.weather directly. Itās important to use the commentary channel for this tool call. Iām ready to proceed and get that weather information!\",\"tool_calls\":[{\"id\":\"call_V9rp4VzfGhqfligrK0CjAvky\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"**Calling weather tool**\\n\\nIām planning to use the weather tool to fetch data for Florence, Italy. We only need one function call, so I donāt really need to use the multi_tool_use.parallel option, which is for calling multiple functions at once. Instead, I'll call functions.weather directly. Itās important to use the commentary channel for this tool call. Iām ready to proceed and get that weather information!\",\"format\":\"openai-responses-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"gAAAAABo944dZfX4x5upHEO9O6o8FIEssTvKUDKVENphC3oqiFFBWesRyticYRIg5wDWANPnawSFvxjrflYOxJn7dxhKoV4Qk5Vgc40ImuoVGjnDw85-xytqO038cMi7sZYouck0O14iOt78tDVS2dcPDYqcHfG4tQjkWQHJGfY2hS5HgKB1b9w8--ZNdEG_3ssltjlCQQ2zhkQMem5aHpXQuddxGCn8zXaNcnnt4aNfdjkW20q4XZuUBc_bQNrZb-3fptvWhFecSFCF8mX3xZsSbeP5DIEzu7R8TWrMJn4ZHPos6WvOX-7DLVaZfw2WtZok7EjTMYuerKFrZcTWfCmv57iENzDDeCnzzxNwqbn1eOooWvcddK9I0Pk7_WeoeVYovA6g9rMnHDhODLQYrB3-80dgslK6nuQsnPx63pm3Mb7FvzbOPZqlrushqaQDrXSVnG9GxH_imzQ-ZXvsBiUfEZg_hV30F7VkFAJC8TOk0sXwrfQyqj9XV7txK-zg-IHkgMsP95nQ5f37-vJ5R42yb0c1pBZCLl_mNW3WiTP_e4Ghwf8mlKrPqKGn5X8T9JwXqDM4u9QOZAjlTTpkxhAUn9Am4XkldTg5E3OLQYjZjqgAKwgLMUOU2yu1U_szM_VyVceHMsvlDDh4RANYR2hHvECkrdpy7FD2x_UG7kx2dP6bqJrlhO8xVahT66OW8EX-3HJ68rrRSYt3GzuvTavzTkOS-XzroI4zFjQxm4Ye7mUk6BbtpZwYMFBlXRh_7YItH6XdICQYLqhsYGCmQlZoqQfwCZ_lZA-wxzXApcjkNxqWEuKLckwi4Lug3SyrHEtbYtNqTzaS62HsaLfEidhdwLSIL3vxJ09wTI3oyR-wrFrqBel21mCcH5rLUp3qb1OUt0n7ojldhIGfzFuEuPUocaTHr4s5JBaoH4drv55NkrzifQrEbPoq91BcF3Za_lEPtZD-sgVL7X2eEu3d8W58Yf0cBT1kyJNRv6Mu10mGwczdZtZAPmC7vUW_hsrN3Teu2cXARAKE96ouVUydHIXOf30jCNv9wtyWL8OojMkQiIlInR8r1lnXmRYUHrMgIKHfDBSd5pNZS_svvmbAhm6UNfdh6W473vmYCocwooI7DdW-91DZUAW7hTd2FQ9ydmN_iDSmZUYrnEHQYEWyMsT2e41I1RVrNkfp3nsf_TrYZDGYlv8giigeickCQQSXs2qgq68tLRI7h1Niz5RUQ0EMNqcfUlM_R9bC2N2HymCPmPZZWkrEzXgALOUUZWpdlUCoi8OpQ9XFwUzPE2m9KE3hbI1bN1MrgJTMfwYjWYagVgxYxk4ldJL6rIgECbn5ifENIfgLWy2GVI5omyNCvtGhw-CjX5wHM3Oa8lR2nV6qGi7sfonEddk5PgtKL6QyZZ6ylwqugEZZIzkcY1j9zWdblPDq8nHI9o_DNWsy_ixmf6K6016gk1WxCb67iFlqYiC1lYSwJV2_3JkYqrznrAAiskOTDmlmtwwuN2VXRO6buX2X75OpeukxuRBBaO81TKdsWYPWKbzTO4EDZzHRS7QRrQViNDvoUqSgZSe-r5N6Ezj9bFwp3os=\",\"id\":\"rs_09029a2dc312d9a70168f78e1ae6848194985709ebc38f7346\",\"format\":\"openai-responses-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":66,\"completion_tokens\":86,\"total_tokens\":152,\"cost\":0.0009425,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000825,\"upstream_inference_completions_cost\":0.00086},\"completion_tokens_details\":{\"reasoning_tokens\":64,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 394.015334ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 3003
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_V9rp4VzfGhqfligrK0CjAvky","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"openai-responses-v1","index":0,"summary":"**Calling weather tool**\n\nIām planning to use the weather tool to fetch data for Florence, Italy. We only need one function call, so I donāt really need to use the multi_tool_use.parallel option, which is for calling multiple functions at once. Instead, I''ll call functions.weather directly. Itās important to use the commentary channel for this tool call. Iām ready to proceed and get that weather information!","type":"reasoning.summary"},{"data":"gAAAAABo944dZfX4x5upHEO9O6o8FIEssTvKUDKVENphC3oqiFFBWesRyticYRIg5wDWANPnawSFvxjrflYOxJn7dxhKoV4Qk5Vgc40ImuoVGjnDw85-xytqO038cMi7sZYouck0O14iOt78tDVS2dcPDYqcHfG4tQjkWQHJGfY2hS5HgKB1b9w8--ZNdEG_3ssltjlCQQ2zhkQMem5aHpXQuddxGCn8zXaNcnnt4aNfdjkW20q4XZuUBc_bQNrZb-3fptvWhFecSFCF8mX3xZsSbeP5DIEzu7R8TWrMJn4ZHPos6WvOX-7DLVaZfw2WtZok7EjTMYuerKFrZcTWfCmv57iENzDDeCnzzxNwqbn1eOooWvcddK9I0Pk7_WeoeVYovA6g9rMnHDhODLQYrB3-80dgslK6nuQsnPx63pm3Mb7FvzbOPZqlrushqaQDrXSVnG9GxH_imzQ-ZXvsBiUfEZg_hV30F7VkFAJC8TOk0sXwrfQyqj9XV7txK-zg-IHkgMsP95nQ5f37-vJ5R42yb0c1pBZCLl_mNW3WiTP_e4Ghwf8mlKrPqKGn5X8T9JwXqDM4u9QOZAjlTTpkxhAUn9Am4XkldTg5E3OLQYjZjqgAKwgLMUOU2yu1U_szM_VyVceHMsvlDDh4RANYR2hHvECkrdpy7FD2x_UG7kx2dP6bqJrlhO8xVahT66OW8EX-3HJ68rrRSYt3GzuvTavzTkOS-XzroI4zFjQxm4Ye7mUk6BbtpZwYMFBlXRh_7YItH6XdICQYLqhsYGCmQlZoqQfwCZ_lZA-wxzXApcjkNxqWEuKLckwi4Lug3SyrHEtbYtNqTzaS62HsaLfEidhdwLSIL3vxJ09wTI3oyR-wrFrqBel21mCcH5rLUp3qb1OUt0n7ojldhIGfzFuEuPUocaTHr4s5JBaoH4drv55NkrzifQrEbPoq91BcF3Za_lEPtZD-sgVL7X2eEu3d8W58Yf0cBT1kyJNRv6Mu10mGwczdZtZAPmC7vUW_hsrN3Teu2cXARAKE96ouVUydHIXOf30jCNv9wtyWL8OojMkQiIlInR8r1lnXmRYUHrMgIKHfDBSd5pNZS_svvmbAhm6UNfdh6W473vmYCocwooI7DdW-91DZUAW7hTd2FQ9ydmN_iDSmZUYrnEHQYEWyMsT2e41I1RVrNkfp3nsf_TrYZDGYlv8giigeickCQQSXs2qgq68tLRI7h1Niz5RUQ0EMNqcfUlM_R9bC2N2HymCPmPZZWkrEzXgALOUUZWpdlUCoi8OpQ9XFwUzPE2m9KE3hbI1bN1MrgJTMfwYjWYagVgxYxk4ldJL6rIgECbn5ifENIfgLWy2GVI5omyNCvtGhw-CjX5wHM3Oa8lR2nV6qGi7sfonEddk5PgtKL6QyZZ6ylwqugEZZIzkcY1j9zWdblPDq8nHI9o_DNWsy_ixmf6K6016gk1WxCb67iFlqYiC1lYSwJV2_3JkYqrznrAAiskOTDmlmtwwuN2VXRO6buX2X75OpeukxuRBBaO81TKdsWYPWKbzTO4EDZzHRS7QRrQViNDvoUqSgZSe-r5N6Ezj9bFwp3os=","format":"openai-responses-v1","id":"rs_09029a2dc312d9a70168f78e1ae6848194985709ebc38f7346","index":0,"type":"reasoning.encrypted"}]},{"content":"40 C","tool_call_id":"call_V9rp4VzfGhqfligrK0CjAvky","role":"tool"}],"model":"openai/gpt-5","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054238-xQNrpePK82YW0rGinOOz\",\"provider\":\"OpenAI\",\"model\":\"openai/gpt-5\",\"object\":\"chat.completion\",\"created\":1761054238,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"completed\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"Right now in Florence, Italy, itās 40°C (about 104°F). Would you like details like wind, humidity, or a forecast?\",\"refusal\":null,\"reasoning\":\"**Reporting Florence weather**\\n\\nThe tool says the temperature in Florence is 40°C, which is extremely hot. I plan to present this clearly: āItās 40°C (104°F) right now.ā The user asked specifically about Florenceās weather, but since I only have the temperature, Iāll let them know that if they want more details like the forecast, humidity, or wind information, they can ask. Iāll keep the formatting minimal and straightforward!\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"**Reporting Florence weather**\\n\\nThe tool says the temperature in Florence is 40°C, which is extremely hot. I plan to present this clearly: āItās 40°C (104°F) right now.ā The user asked specifically about Florenceās weather, but since I only have the temperature, Iāll let them know that if they want more details like the forecast, humidity, or wind information, they can ask. Iāll keep the formatting minimal and straightforward!\",\"format\":\"openai-responses-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"gAAAAABo944jF01C67U4zDS7nK1XiLlkDBfH87ZsVtc4nIRLaWALjHhJRqXKuNPEL-ImKNW49wXPUm0uwziVgchbOw_cUOQDdsocetEHg4UDFCq_Qqm7wdAesjwQSMXeuN0XF3yuO6rLa33kPRPzA9sh-Y-SiXnX_B1jjaVpztt-XlWZrAemaFQk_5qehuqVG83MZqQT4CL1x5TwXHQW4MrmYzVRC_gneZGtEXrmY0Dk_2nNGsogFgsb8obWNouVI43UexMaxkZe3CNN2hOUz0Wy3j46ErR4th8VDFK3eebzpsdsHWkvVva4_2hAhEQFgDgAknQVY1TiCTEVg0jcvpOCuVLb41RXax4atO1tYAYvyutG1NK_MNGpjlmRwQuPk3yFXNoSvHq4kb1_YK4RZYLlcJSkzFxXSGWgKzttv9T8eaA6_oRWUu1MZEQSrIrwyMDic5ZwBBoJyuFobknZ9V8Lt2syWDgarOBwvuRE075xIHLAMPP4gE4eB6Z_AMpD6evadjBSdc3HxX96qhGAuINehOjhhAQ_-j4-fu3knAEKb3uoR7e4tAu5voW9f0Q4eutLZSzDMz_ARloK3gd3mCCZbQBPGJIuMA9kHQAqUpmYWrqimIM9OJZ9RowU3Bnhi4L63f-4iWB5Ebb5z4gjuRwKn6BI5n_8VkimJgSLYYQfXBl5YOsk2k0JnfjX7lFMbVAiHxnxwSn7ekD2-Js_mw0GSBkRx_rutRlXrQ8B09qnvoy-S1zlZC9EowksQtTLjt-RKwqtBZoKu0USOpMuRNibBqybcR55MTWlsuqj2DNiL1p5jPW3tqJsYQj5kLW2J9SsH96vfpufEnfykt1inLfqQyy-v1MKge9Chuq3Z_wKtfkmVY5n8CPryXIngSrI6965uxK292BDS-k7LlvYU8kwN_m1ILm2i4r7YY-rSZkoKPrKL7IGomhjr9mw3wNK4Ta27uw4syVyRLyQ0gl6FnmPJcRcbsWb774C6JTYklHa-jJXNLL_AHeBZbBAR3Too5Cvk_ZTLQQXsPHNqD6us2vLqUlJHtJLJTiR98XOt_pDfCBKHm0EZyeSL2fq9FOUCY32-F4uPeZEROd1zZF-Tx0j45VlePpTAYZ7JQEvuOrH89iAPw8JwxgZgqcWqI3Ky9cZF5-d5Lxs2C_KoNMcvXr7gTjaOXsKEs0C529sdpo-Yfd_WyZj8LI46L70qmBF7n66hDsKQjyyVdb8x9u3UAbURtlROhXOx_E8hK0S9QeN4VIlfi2GPfysvADSesWdWMx0FmVaLYX9IXpuOh15cfCLl6Oob1GjUrvlEDown_6GUOW20ZJIJG8s_s8wjTa7TvlCaVF8B1f7rq1RtlnscAswMFRW5itVj3Fcz83W6cUx4nuvPifs3_MrQ1Ef6ErfizAbC_o2ZOs0WMr5XAfNBITgCb_JiNmjoZKrMhEpXLkpgDE1JYZw9NlGtwBJaE1GbtOP5cNDIZMjcqms75vej-gqS6CqzWm7DsPxoOabYlROMMJveFiEdtLNZUXwaLN8cOU84t9BRSuo64yNRHgHyVlvTKwTy5uodoivkgWh5xZ4cx_ro396f-fpCAVaWQ6Zfd3LVCAqkMxkJKR7MJlQ7mGrSf-Z1XVs-G2gJ0ST4PFa_Mflww0r-P3igvzbr1quOBwxgHKU7oozO6lws47aeMJxdeODrDN0zw==\",\"id\":\"rs_09029a2dc312d9a70168f78e1f6924819494d36d087f855215\",\"format\":\"openai-responses-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":204,\"completion_tokens\":165,\"total_tokens\":369,\"cost\":0.001905,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.000255,\"upstream_inference_completions_cost\":0.00165},\"completion_tokens_details\":{\"reasoning_tokens\":128,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 729.454917ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/tool_streaming.yaml
new file mode 100644
index 000000000..363c14627
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/gpt-5/tool_streaming.yaml
@@ -0,0 +1,567 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 544
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"openai/gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"**Getting","reasoning_details":[{"type":"reasoning.summary","summary":"**Getting","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.summary","summary":" weather","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.summary","summary":" for","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.summary","summary":" Florence","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"**\n\nI","reasoning_details":[{"type":"reasoning.summary","summary":"**\n\nI","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" need","reasoning_details":[{"type":"reasoning.summary","summary":" need","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.summary","summary":" to","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" respond","reasoning_details":[{"type":"reasoning.summary","summary":" respond","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" with","reasoning_details":[{"type":"reasoning.summary","summary":" with","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.summary","summary":" weather","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" info","reasoning_details":[{"type":"reasoning.summary","summary":" info","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" using","reasoning_details":[{"type":"reasoning.summary","summary":" using","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.summary","summary":" weather","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" tool","reasoning_details":[{"type":"reasoning.summary","summary":" tool","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.summary","summary":" for","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.summary","summary":" Florence","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" don't","reasoning_details":[{"type":"reasoning.summary","summary":" don't","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" need","reasoning_details":[{"type":"reasoning.summary","summary":" need","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.summary","summary":" to","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" use","reasoning_details":[{"type":"reasoning.summary","summary":" use","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" multi","reasoning_details":[{"type":"reasoning.summary","summary":" multi","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"-tool","reasoning_details":[{"type":"reasoning.summary","summary":"-tool","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" options","reasoning_details":[{"type":"reasoning.summary","summary":" options","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" since","reasoning_details":[{"type":"reasoning.summary","summary":" since","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" only","reasoning_details":[{"type":"reasoning.summary","summary":" only","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" need","reasoning_details":[{"type":"reasoning.summary","summary":" need","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" one","reasoning_details":[{"type":"reasoning.summary","summary":" one","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" tool","reasoning_details":[{"type":"reasoning.summary","summary":" tool","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" which","reasoning_details":[{"type":"reasoning.summary","summary":" which","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" will","reasoning_details":[{"type":"reasoning.summary","summary":" will","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" be","reasoning_details":[{"type":"reasoning.summary","summary":" be","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" functions","reasoning_details":[{"type":"reasoning.summary","summary":" functions","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".weather","reasoning_details":[{"type":"reasoning.summary","summary":".weather","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Once","reasoning_details":[{"type":"reasoning.summary","summary":" Once","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" get","reasoning_details":[{"type":"reasoning.summary","summary":" get","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" results","reasoning_details":[{"type":"reasoning.summary","summary":" results","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"āll","reasoning_details":[{"type":"reasoning.summary","summary":"āll","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" parse","reasoning_details":[{"type":"reasoning.summary","summary":" parse","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.summary","summary":" and","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" share","reasoning_details":[{"type":"reasoning.summary","summary":" share","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" key","reasoning_details":[{"type":"reasoning.summary","summary":" key","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" data","reasoning_details":[{"type":"reasoning.summary","summary":" data","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" back","reasoning_details":[{"type":"reasoning.summary","summary":" back","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" with","reasoning_details":[{"type":"reasoning.summary","summary":" with","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.summary","summary":" user","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" also","reasoning_details":[{"type":"reasoning.summary","summary":" also","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" want","reasoning_details":[{"type":"reasoning.summary","summary":" want","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.summary","summary":" to","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" confirm","reasoning_details":[{"type":"reasoning.summary","summary":" confirm","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" that","reasoning_details":[{"type":"reasoning.summary","summary":" that","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.summary","summary":" user","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" means","reasoning_details":[{"type":"reasoning.summary","summary":" means","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.summary","summary":" Florence","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Italy","reasoning_details":[{"type":"reasoning.summary","summary":" Italy","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.summary","summary":" and","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" not","reasoning_details":[{"type":"reasoning.summary","summary":" not","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.summary","summary":" Florence","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" South","reasoning_details":[{"type":"reasoning.summary","summary":" South","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Carolina","reasoning_details":[{"type":"reasoning.summary","summary":" Carolina","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" but","reasoning_details":[{"type":"reasoning.summary","summary":" but","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" they","reasoning_details":[{"type":"reasoning.summary","summary":" they","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" specified","reasoning_details":[{"type":"reasoning.summary","summary":" specified","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Italy","reasoning_details":[{"type":"reasoning.summary","summary":" Italy","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" So","reasoning_details":[{"type":"reasoning.summary","summary":" So","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I'll","reasoning_details":[{"type":"reasoning.summary","summary":" I'll","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" move","reasoning_details":[{"type":"reasoning.summary","summary":" move","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ahead","reasoning_details":[{"type":"reasoning.summary","summary":" ahead","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" with","reasoning_details":[{"type":"reasoning.summary","summary":" with","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" calling","reasoning_details":[{"type":"reasoning.summary","summary":" calling","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" functions","reasoning_details":[{"type":"reasoning.summary","summary":" functions","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".weather","reasoning_details":[{"type":"reasoning.summary","summary":".weather","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.summary","summary":" for","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.summary","summary":" Florence","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Italy","reasoning_details":[{"type":"reasoning.summary","summary":" Italy","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"!","reasoning_details":[{"type":"reasoning.summary","summary":"!","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.encrypted","data":"gAAAAABo944oUBwTfrWO9GdeunsvJN2ki803MVwIuDM5hnEdDRtlwD-76GsW73tJQ8E8GFrP6FHHbXbErq-YRjChHvsLxbIetlPZRAhjalWdvurrCx5G41KCpZ3DRdYis62KjWlJjCf3dc7z7uecOCRa_FOQceBz1LaTDjSuPbAAwoJ6wEUXvoRAxefcQ5OU3OBhkRuKSdX-ebpudC7hYY8mLNghh4XIbw-Rtikl4xtyJGyz5dCkgDa5b09yTjs0FErQhfVvmr5yyTmisQFjzR3vv9B72-dvRPkHuhfGuai9UbShAB0HD0nYRHkIKPDsZuWpp0x0OdcAgiaY2dS9KMscT0sH-z0SbOd4eavSVmhnW1Qfn-JiXvDQ0shFohIbJ4afIo3Hjc_1amkU4T8n3lh9tQhHznvGw7Qw_g9pHBEkSMRl6D6k81i3W3WXADqRVItt0aSZFq65MQtxsWt2IHeBT8zGwXL07EU5gnOukHjlPgeuyF6esUvRgTNMMqcw2CtxbwG5ZMFeMqq5MmuXLWltd8UTMZoNpu2GtwLgC5dbsoDrWDndHFhidFGrqsH5F5RWPsn1gLCQFc6bsYSruGKNUwq_qbT-Xi08V096VOju2VJE9A5AFqbcAdxITWPDBiwd8ewAMzXsREL-oBrWCWH-6OedhdDFCTDWQ3GA8u1Lrkesb0_dcyJNsLm4JqQRe-Lv8zbgNyFEoPgYpoF-Nw9GXIKpDTSsYj46Qju8rknDHwADdwkbhO_Ez9yBGT_Ys1Rc3PLhiYZ2dNI1bWiPEnC7RT8O0-8nbl3FGGoDQx6KO_0pnjRli5K11f60idsg1mZMu_Ozo3Tu_DnMWCU_rFBRlld2Wwku0ZxilBRyWZ_rWjzc-RFlrN7RH6C8sAfSuLzu15vbO07OiZ3eE6yB7szCbKeolJrLfacgLn8tbvyJyaHP50drYKOQr7gz_Yu1YWiDKQZiqETQLdEaEK3N2v75BQOB9gNKgQKSSSmPgsvZClGAwDixZVIF6vjzHoKPBJd9DlhdfXewrsbDcJvx0VSAjLWfio7xktJFliIMQXOfOhc6T8bF7BwDkCq1oXwiSccCHcW5sDpBlDXFA9hHbid7Z2N9hf9lDLekuwE9fyWTJ29ly59QvXbfbeqbkSwtX58C8sy6VPWVjpZlRq6J_26sF6x-0JgYPMbzKRVt5vx-kRPveZnHf5K21HzW8Yk6mEx6wHjh2qdc7cqiMUtZlkl4TrpLDar_FnTRaeRVLIRTnzISWpGDjFBLBqgzkD4XwqJxYJld-H64T2mTy0p12HPSlJpDNOaDV-ec-qT82qWyT_plTRQiKV7cv9JynFxjRvjfTjoAKpxBcZE1KEGer0IPiNLxmFx7gct0MwgJ4phEupRcGSKROxjTssMf83zW4ZEu49jgnMy-IRTa_jrIgnz4xUAsOrbJFlkNr8C1wYk1gWy3a06PHnXkIUyU6BP1C3lVuwzWke9VhilyTaP5gMbIJtjDFWsPlNdpkwEuhxztSV8WztXoLXSTrwA3SudwUhIB-Oy3K-YZ1gOG_vQWSvNAhAZGim57vAY8TRrWtxlpcddefqoS14OV7Zu0uwxo8n6dsEsIYz7isZhWq0dZmRNmoR-avTH8DFnw7Gajc4dJOTgwnS5g2Or75l0ccBnh6KrJCDwcv1n7MZ_0DR7ETEjEUzFBpejsNU0189xap_tZ811yz3o8rPhk30uk86Ry9s9KrMvUx1r1hsBr5CGD8AAwgwmUOrp4Q2JMPIxgohDHqg5wkPT_QOhi7fPjxPlQd_vPUmGiTy7szdiEdKQsMTq45AAzkYQWrK88mmYXWQxXoGbExDhMzVF-Hkjkgds5dmlRsd_aARk6pKhHpuulHmGDWALKgDtb_4ANmsmLHUttN6-JwQplvSn3aF7ZYKCUBOUTrcKP5FmbHkrLOS9RhKoSez26E5qheE9YnEe6lf8uMmBg-dP556o=","id":"rs_0ade41fe199e8ca80168f78e2482888193a6d6d2d8326ae014","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"call_ZpSbEsBRkwjfjIG4x89HQzml","index":0,"type":"function","function":{"name":"weather","arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"{\""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"location"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"\":\""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"Flor"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"ence"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":","}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":" Italy"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"\"}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"tool_calls","native_finish_reason":"completed","logprobs":null}]}
+
+ data: {"id":"gen-1761054243-GWvbh93pSOkiPd5iXJz7","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054243,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":66,"completion_tokens":150,"total_tokens":216,"cost":0.0015825,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000825,"upstream_inference_completions_cost":0.0015},"completion_tokens_details":{"reasoning_tokens":128,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 560.498125ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 3502
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_ZpSbEsBRkwjfjIG4x89HQzml","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"openai-responses-v1","index":0,"summary":"**Getting weather for Florence**\n\nI need to respond with the weather info using the weather tool for Florence. I don''t need to use multi-tool options since I only need one tool, which will be functions.weather. Once I get the results, Iāll parse and share the key data back with the user. I also want to confirm that the user means Florence, Italy and not Florence, South Carolina, but they specified Italy. So I''ll move ahead with calling functions.weather for Florence, Italy!","type":"reasoning.summary"},{"data":"gAAAAABo944oUBwTfrWO9GdeunsvJN2ki803MVwIuDM5hnEdDRtlwD-76GsW73tJQ8E8GFrP6FHHbXbErq-YRjChHvsLxbIetlPZRAhjalWdvurrCx5G41KCpZ3DRdYis62KjWlJjCf3dc7z7uecOCRa_FOQceBz1LaTDjSuPbAAwoJ6wEUXvoRAxefcQ5OU3OBhkRuKSdX-ebpudC7hYY8mLNghh4XIbw-Rtikl4xtyJGyz5dCkgDa5b09yTjs0FErQhfVvmr5yyTmisQFjzR3vv9B72-dvRPkHuhfGuai9UbShAB0HD0nYRHkIKPDsZuWpp0x0OdcAgiaY2dS9KMscT0sH-z0SbOd4eavSVmhnW1Qfn-JiXvDQ0shFohIbJ4afIo3Hjc_1amkU4T8n3lh9tQhHznvGw7Qw_g9pHBEkSMRl6D6k81i3W3WXADqRVItt0aSZFq65MQtxsWt2IHeBT8zGwXL07EU5gnOukHjlPgeuyF6esUvRgTNMMqcw2CtxbwG5ZMFeMqq5MmuXLWltd8UTMZoNpu2GtwLgC5dbsoDrWDndHFhidFGrqsH5F5RWPsn1gLCQFc6bsYSruGKNUwq_qbT-Xi08V096VOju2VJE9A5AFqbcAdxITWPDBiwd8ewAMzXsREL-oBrWCWH-6OedhdDFCTDWQ3GA8u1Lrkesb0_dcyJNsLm4JqQRe-Lv8zbgNyFEoPgYpoF-Nw9GXIKpDTSsYj46Qju8rknDHwADdwkbhO_Ez9yBGT_Ys1Rc3PLhiYZ2dNI1bWiPEnC7RT8O0-8nbl3FGGoDQx6KO_0pnjRli5K11f60idsg1mZMu_Ozo3Tu_DnMWCU_rFBRlld2Wwku0ZxilBRyWZ_rWjzc-RFlrN7RH6C8sAfSuLzu15vbO07OiZ3eE6yB7szCbKeolJrLfacgLn8tbvyJyaHP50drYKOQr7gz_Yu1YWiDKQZiqETQLdEaEK3N2v75BQOB9gNKgQKSSSmPgsvZClGAwDixZVIF6vjzHoKPBJd9DlhdfXewrsbDcJvx0VSAjLWfio7xktJFliIMQXOfOhc6T8bF7BwDkCq1oXwiSccCHcW5sDpBlDXFA9hHbid7Z2N9hf9lDLekuwE9fyWTJ29ly59QvXbfbeqbkSwtX58C8sy6VPWVjpZlRq6J_26sF6x-0JgYPMbzKRVt5vx-kRPveZnHf5K21HzW8Yk6mEx6wHjh2qdc7cqiMUtZlkl4TrpLDar_FnTRaeRVLIRTnzISWpGDjFBLBqgzkD4XwqJxYJld-H64T2mTy0p12HPSlJpDNOaDV-ec-qT82qWyT_plTRQiKV7cv9JynFxjRvjfTjoAKpxBcZE1KEGer0IPiNLxmFx7gct0MwgJ4phEupRcGSKROxjTssMf83zW4ZEu49jgnMy-IRTa_jrIgnz4xUAsOrbJFlkNr8C1wYk1gWy3a06PHnXkIUyU6BP1C3lVuwzWke9VhilyTaP5gMbIJtjDFWsPlNdpkwEuhxztSV8WztXoLXSTrwA3SudwUhIB-Oy3K-YZ1gOG_vQWSvNAhAZGim57vAY8TRrWtxlpcddefqoS14OV7Zu0uwxo8n6dsEsIYz7isZhWq0dZmRNmoR-avTH8DFnw7Gajc4dJOTgwnS5g2Or75l0ccBnh6KrJCDwcv1n7MZ_0DR7ETEjEUzFBpejsNU0189xap_tZ811yz3o8rPhk30uk86Ry9s9KrMvUx1r1hsBr5CGD8AAwgwmUOrp4Q2JMPIxgohDHqg5wkPT_QOhi7fPjxPlQd_vPUmGiTy7szdiEdKQsMTq45AAzkYQWrK88mmYXWQxXoGbExDhMzVF-Hkjkgds5dmlRsd_aARk6pKhHpuulHmGDWALKgDtb_4ANmsmLHUttN6-JwQplvSn3aF7ZYKCUBOUTrcKP5FmbHkrLOS9RhKoSez26E5qheE9YnEe6lf8uMmBg-dP556o=","format":"openai-responses-v1","id":"rs_0ade41fe199e8ca80168f78e2482888193a6d6d2d8326ae014","index":0,"type":"reasoning.encrypted"}]},{"content":"40 C","tool_call_id":"call_ZpSbEsBRkwjfjIG4x89HQzml","role":"tool"}],"model":"openai/gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"**Preparing","reasoning_details":[{"type":"reasoning.summary","summary":"**Preparing","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.summary","summary":" weather","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" response","reasoning_details":[{"type":"reasoning.summary","summary":" response","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"**\n\nThe","reasoning_details":[{"type":"reasoning.summary","summary":"**\n\nThe","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" tool","reasoning_details":[{"type":"reasoning.summary","summary":" tool","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" is","reasoning_details":[{"type":"reasoning.summary","summary":" is","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" showing","reasoning_details":[{"type":"reasoning.summary","summary":" showing","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" 40","reasoning_details":[{"type":"reasoning.summary","summary":" 40","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"°C","reasoning_details":[{"type":"reasoning.summary","summary":"°C","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" which","reasoning_details":[{"type":"reasoning.summary","summary":" which","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" feels","reasoning_details":[{"type":"reasoning.summary","summary":" feels","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" really","reasoning_details":[{"type":"reasoning.summary","summary":" really","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" hot","reasoning_details":[{"type":"reasoning.summary","summary":" hot","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ā","reasoning_details":[{"type":"reasoning.summary","summary":"ā","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"maybe","reasoning_details":[{"type":"reasoning.summary","summary":"maybe","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" it's","reasoning_details":[{"type":"reasoning.summary","summary":" it's","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" just","reasoning_details":[{"type":"reasoning.summary","summary":" just","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.summary","summary":" a","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" joke","reasoning_details":[{"type":"reasoning.summary","summary":" joke","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"!","reasoning_details":[{"type":"reasoning.summary","summary":"!","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" should","reasoning_details":[{"type":"reasoning.summary","summary":" should","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" say","reasoning_details":[{"type":"reasoning.summary","summary":" say","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" it","reasoning_details":[{"type":"reasoning.summary","summary":" it","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ās","reasoning_details":[{"type":"reasoning.summary","summary":"ās","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" about","reasoning_details":[{"type":"reasoning.summary","summary":" about","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" 40","reasoning_details":[{"type":"reasoning.summary","summary":" 40","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"°C","reasoning_details":[{"type":"reasoning.summary","summary":"°C","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.summary","summary":" and","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" convert","reasoning_details":[{"type":"reasoning.summary","summary":" convert","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" it","reasoning_details":[{"type":"reasoning.summary","summary":" it","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.summary","summary":" to","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Fahrenheit","reasoning_details":[{"type":"reasoning.summary","summary":" Fahrenheit","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" which","reasoning_details":[{"type":"reasoning.summary","summary":" which","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" is","reasoning_details":[{"type":"reasoning.summary","summary":" is","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" 104","reasoning_details":[{"type":"reasoning.summary","summary":" 104","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"°F","reasoning_details":[{"type":"reasoning.summary","summary":"°F","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" want","reasoning_details":[{"type":"reasoning.summary","summary":" want","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.summary","summary":" to","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" keep","reasoning_details":[{"type":"reasoning.summary","summary":" keep","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" it","reasoning_details":[{"type":"reasoning.summary","summary":" it","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" concise","reasoning_details":[{"type":"reasoning.summary","summary":" concise","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" so","reasoning_details":[{"type":"reasoning.summary","summary":" so","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I'll","reasoning_details":[{"type":"reasoning.summary","summary":" I'll","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" provide","reasoning_details":[{"type":"reasoning.summary","summary":" provide","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.summary","summary":" a","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" little","reasoning_details":[{"type":"reasoning.summary","summary":" little","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" hydration","reasoning_details":[{"type":"reasoning.summary","summary":" hydration","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" advice","reasoning_details":[{"type":"reasoning.summary","summary":" advice","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" too","reasoning_details":[{"type":"reasoning.summary","summary":" too","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I'll","reasoning_details":[{"type":"reasoning.summary","summary":" I'll","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" say","reasoning_details":[{"type":"reasoning.summary","summary":" say","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.summary","summary":" \"","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"It's","reasoning_details":[{"type":"reasoning.summary","summary":"It's","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" currently","reasoning_details":[{"type":"reasoning.summary","summary":" currently","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" about","reasoning_details":[{"type":"reasoning.summary","summary":" about","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" 40","reasoning_details":[{"type":"reasoning.summary","summary":" 40","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"°C","reasoning_details":[{"type":"reasoning.summary","summary":"°C","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" (","reasoning_details":[{"type":"reasoning.summary","summary":" (","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"104","reasoning_details":[{"type":"reasoning.summary","summary":"104","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"°F","reasoning_details":[{"type":"reasoning.summary","summary":"°F","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":")","reasoning_details":[{"type":"reasoning.summary","summary":")","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" in","reasoning_details":[{"type":"reasoning.summary","summary":" in","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.summary","summary":" Florence","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Italy","reasoning_details":[{"type":"reasoning.summary","summary":" Italy","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Stay","reasoning_details":[{"type":"reasoning.summary","summary":" Stay","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" hydrated","reasoning_details":[{"type":"reasoning.summary","summary":" hydrated","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.summary","summary":" and","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" think","reasoning_details":[{"type":"reasoning.summary","summary":" think","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" about","reasoning_details":[{"type":"reasoning.summary","summary":" about","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" wearing","reasoning_details":[{"type":"reasoning.summary","summary":" wearing","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" light","reasoning_details":[{"type":"reasoning.summary","summary":" light","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" clothing","reasoning_details":[{"type":"reasoning.summary","summary":" clothing","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Would","reasoning_details":[{"type":"reasoning.summary","summary":" Would","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" you","reasoning_details":[{"type":"reasoning.summary","summary":" you","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" like","reasoning_details":[{"type":"reasoning.summary","summary":" like","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" forecast","reasoning_details":[{"type":"reasoning.summary","summary":" forecast","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.summary","summary":" for","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" next","reasoning_details":[{"type":"reasoning.summary","summary":" next","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" few","reasoning_details":[{"type":"reasoning.summary","summary":" few","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" days","reasoning_details":[{"type":"reasoning.summary","summary":" days","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"?\"","reasoning_details":[{"type":"reasoning.summary","summary":"?\"","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" It","reasoning_details":[{"type":"reasoning.summary","summary":" It","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ās","reasoning_details":[{"type":"reasoning.summary","summary":"ās","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" important","reasoning_details":[{"type":"reasoning.summary","summary":" important","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.summary","summary":" to","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" keep","reasoning_details":[{"type":"reasoning.summary","summary":" keep","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" it","reasoning_details":[{"type":"reasoning.summary","summary":" it","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" brief","reasoning_details":[{"type":"reasoning.summary","summary":" brief","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.summary","summary":" and","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" helpful","reasoning_details":[{"type":"reasoning.summary","summary":" helpful","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"!","reasoning_details":[{"type":"reasoning.summary","summary":"!","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.encrypted","data":"gAAAAABo944wLRDjvEOj3nKSFQ-kq_5YJy3QHZtwv1BhE3K0L6KNHoBh7QRRz9AwhZy1V2sCjc_BgDKls_8GbnhJ_Bpj-XxM9t-26NQdrYbEfp4biQLPP8XsNYlTc6POCOeWfRws_n_x4AJiwy29OHOvtDidzOb2ykws18-8jud64wSbFA7M3pe1tZD2HVIwh9echOg9NY9mvoW3ZkLT2ufOklVoGGbj6bTbelafiz5iLhU2SwiT6X5wf2qkmsRvXZzSnbwwJLiMNopfOkQucSY4UL051vCl1WUiH_X6Q0yC4ZfxfjkVH6jOMvcnp3-vDBWKYDvUgNrcyz2p_rKEncvF8BVBnWK9JlkuxmqnGY7ThVfLpCfYhIYIZ1xlRyhnJvC9HwHGYuRR4zTSE183OBw8knOgbxUTmz9bBJM5k1CRFNnMxj6gVI4Q4LAqDRWMxFDmJaHlOFWW2NMus5OyAa4qiRjtjMJmDS_KbuoSBiWlqzDjnCTDnNyylhXxs341tRLuvs3kN1lUEpMCUG31iWsLdJv4h1JRc8nMuHTrHrjbEiJzgSdjaKnHsrb8xeaMK3fN6oEsn-0prsnvWVuQu8zNVeLQ97XSAtgHrUIshH1mewqdiAWLN6XNxYccObg6SKAbNWU9de2ZjA-9wFscwJnTs05Ml_7pXSQKj5kmOYsf4lq8VKLpm9GSQUCm86e2mOTjSPtHrNAFrLc-nXSH_3JKVTLSHlA2DA4TTxGZ-HleetkbSG37txzjNevEVtcA6eywj_haP-o87zR-YP-oKKN37pXXD5lNtNEBxfUfyFPeBCwyXOViJ3l9G6Yc6raSO7v3WhiA_HUHPyR6CoLJ1LzH7X7F88wwHOfoiWvE3ul5Jo5q0hZYpvBk2CMYZmNfqjf8PbxkuClPRI6KiUNapPr3RbcRtIp2O16iWkK28cKp3Yvyl35AZBhHb9nVOS10xKvyLyDVmK4tpO8MpFdz4RZTV-jGQnkXNJBkZ-20kaZ_Zj6TC8YNeA5-rGP4aZCJkPy0yylkOhcv48OH59X-7_XPyB9ub9nJq8uLOwkzujnp8r8PPgd4WAz2jMIhWkmHG6JAcrRZDkf8libMF8LRewLTE5gqBM8hvglApWwJUIs_JLBAFrH2DG65c3p7m0jp0KL-xTJ-GsF9bWc9CmOZ65D8drQDmOa73aF7FqRFhNldr3T6si9yRPYRAXdrHoKoNorZSanxI6yb1ne_WrAL4gxu8oW5yaX9ZFjXfZ8l_N46fpW2h1LAhyV2peqGCZSqwHKaU6GzJUZ443Kr2hjFx0eerncOhFSDTjF1w-_fmsga_Jj_NEVPhrPmddKBdiZB4OqU_qFCOk7QTZVGqs7xAI6dzwjwkwj-2BzyAnnn45-KD7vnR9Vcko7o_LRxHBfJ66kNOiTnup_2l0SW0o1nHfr4E5TQZNNP_eY3nY36Lq4bFoqYgew00PaA3mz3UBR1Q0QYzUzM-_Tuz8vt0daWvn6AAvHKM6SQxnSq6AqsPySHgCSNxA0EL9Yf-CMRLREGUBiMZqpbMUObpvgouTpq59iHyXE0SOZir7rrEYT8g_h6MIo_Bp-dUW0aAMgUpqs5YQtjS9k-PpiHqWnAl1DMdT9y-tMZrjItYF6daFIiUrpW5mNJ_G84LbkTg5LU6JAkBvfhSmzeYaRKccWXLn31bXSscHpFmgv7lxYn5cLgWmhVD0VTKbOGeqnJ6DBuOZTc0wJpYruS7FrW1la5EhMMw-OxcSiHS82mk2ZwFvsChd_GGPMO4O5ruu-7H4REck9LmH3edFm7ellEqShciVzSTw8mNWegjVY8EqLNpdit_MLbDScfxZbEcdZAWlGWSXtDnVQLoibfel10","id":"rs_0ade41fe199e8ca80168f78e2a4544819397637abfbe3dcdef","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"It"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"ās"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" currently"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" about"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"40"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"°C"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" ("},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"104"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"°F"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":")"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" in"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" Florence"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":","},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" Italy"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"."},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" Stay"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" hydrated"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" and"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" avoid"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" peak"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" afternoon"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" sun"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"."},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" Want"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" a"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" short"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" forecast"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" for"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" the"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" next"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" few"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":" days"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":"?"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"completed","logprobs":null}]}
+
+ data: {"id":"gen-1761054248-GgPiWSgpQ9fJFpVLY56l","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054248,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":271,"completion_tokens":168,"total_tokens":439,"cost":0.00201875,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00033875,"upstream_inference_completions_cost":0.00168},"completion_tokens_details":{"reasoning_tokens":128,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 756.661458ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/multi_tool.yaml
new file mode 100644
index 000000000..6a0d87f2f
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 851
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"x-ai/grok-code-fast-1","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054142-eYAg1TS29ynxKrGihXi4\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion\",\"created\":1761054142,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"completed\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":\"The user wants to add and multiply 2 and 3. There are tools for add and multiply, and the instruction says to always use both add and multiply at the same time.\\n\\n\\n## Handling user calculation\\n\\n- The user needs to perform addition and multiplication with the numbers 2 and 3.\",\"tool_calls\":[{\"id\":\"call_11576212\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"add\",\"arguments\":\"{\\\"a\\\":2,\\\"b\\\":3}\"}},{\"id\":\"call_73433553\",\"index\":1,\"type\":\"function\",\"function\":{\"name\":\"multiply\",\"arguments\":\"{\\\"a\\\":2,\\\"b\\\":3}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"The user wants to add and multiply 2 and 3. There are tools for add and multiply, and the instruction says to always use both add and multiply at the same time.\\n\\n\\n## Handling user calculation\\n\\n- The user needs to perform addition and multiplication with the numbers 2 and 3.\",\"format\":\"xai-responses-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"gLfiMDfyjmfStOk6GOQ4aXtkwzRIjhGm+zvLHyQHiorECxqk6/nYU4IS/zUK+fFFd0dBKmsny+h8GwRN+OiiUa21Xy7iKf81aD60JOp8LkDLjQ3S9dxEoVTRroOTYAkH5Jx63vn7bgIoT8VDWcuFY2aa66JE/IXNC3I2hBEC6ntKtChcu/4m303kcyp8JBVIzGb2DLgg51e/UwTEToE6LbCCMKEpkHly9yL5VVq7fDH2mNu1RwBHIcAzyWCKYgdUn9BWAbjGvZF8NSqA3g3gJjkPFemhGqSvMONqxhhaIb29GdbIAFZY+d4+dGolb3KITRkg2Oib223hhfwQqaBMPp6nwmiqhIcr9uqVNYTag50O2mLNUvrlh4p8bvi52UI1mt2krhrRZ8H44+Kdi1uiwPajqI6RpGFkPIxv6OMDBY/rwRmtHVjC/74HB5QizdMa4xEv7X8TP/R6Gl356IDwHlGDqHvE65GgLOL+3Jt0GyoPc5l71j0TwX5/Qq0f79Dl/eU+vwtNP1kryCiYruK1a7Ezeuj/H2rinVmW6jNkfxwSjUntpFIJMucksz0cg4fmxwo/br1FKv/3lSjEJmOaG34mj/0+mDR5GFR8uwdQVBX06nLcdbaZLoA4YlZxgrU6e0MQFsfjEwZq4si0RGwml4rbdjOcKuS9YqJGAKv/LaM3GLEnlLpnKMixX7ztB+9b8gQJMdhvdl/T25MFOWUaSyXo0AHxuviDs++8qRAABamNl8/k251DElVRYYVzpXq7LElavxhn7ijDQ3uzYeK7R1KelnYCAgS4SnHfI5t4cFfwQzDgMxco2VOGUpZ6srXM140442mVkVgqyd8+JGPni6e7W+TQVFcfU/cd2t5QLuthnF+DaAaT035keBY0OmaSlQQop5GbAEoag8UPGA7Xn+nP/fZqDaCxyJnArSiph5sGNOqB1bWVQMVtNumU4yy21852AiB6+cCOZvuWLJ6GmZxlpIDScrxZmA\",\"id\":\"rs_bcbaf157-d66c-01ad-7ceb-24b34ad2926c_us-east-1\",\"format\":\"xai-responses-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":479,\"completion_tokens\":229,\"total_tokens\":708,\"cost\":0.0003817,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":320,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000382,\"upstream_inference_completions_cost\":0.0003435},\"completion_tokens_details\":{\"reasoning_tokens\":161,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 528.732ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1578
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_11576212","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"call_73433553","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"unknown","index":0,"text":"The user wants to add and multiply 2 and 3. There are tools for add and multiply, and the instruction says to always use both add and multiply at the same time.\n\n\n## Handling user calculation\n\n- The user needs to perform addition and multiplication with the numbers 2 and 3.","type":"reasoning.text"}]},{"content":"5","tool_call_id":"call_11576212","role":"tool"},{"content":"6","tool_call_id":"call_73433553","role":"tool"}],"model":"x-ai/grok-code-fast-1","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054144-7XSqRnWBMdsk5sVp4y1Y\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion\",\"created\":1761054144,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"completed\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The sum of 2 and 3 is 5.\\n\\nThe product of 2 and 3 is 6.\",\"refusal\":null,\"reasoning\":\"First, the user asked to add and multiply 2 and 3.\\n\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"First, the user asked to add and multiply 2 and 3.\\n\",\"format\":\"xai-responses-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"xRfwXVzoI7ub4uNstLcVTuu7+WAZZtMt3XMSSdxWm35hkiCzspszDpMG+hE2GkOVNfQwhOJd7yuVjimdu5aQ44NWMwjydTKyqOdxxHUzsnkXQUpO5Y3KSu1ngX1NW7qEx6kLlxTrQPlqUxE1XMgHGaFHZcTGoVcdapm6IchhjrtGqTLnf6Wze8QaqCpmsfw0EhtD9TBAQTfkvgnBoWmAIzh1TsKZBPdjbEv6YC+Y0mjgOZZtKHcYjvAJMJkdVRwrvGVBIrKZmvL2XhWNntuLQKC0s62t8LXHBbko+lWUvm+epgWMlNSIF57HvqKWlosJTkAe6hvBSHagKl/BG6Dc9dQLyLGuT1rQMEpZPC29rupAv2CQopw+RV9OECU9wQYYTqGmVLqgy3gl9QzgVMFsmjYIkMp658e7Wgfoa/J4ZAe/dTDtmMyoB6q4ZTzsv7nsDK+cdtCRwjc\",\"id\":\"rs_52652d80-12d8-ef8e-bb9f-107c5b072aa4_us-east-1\",\"format\":\"xai-responses-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":560,\"completion_tokens\":98,\"total_tokens\":658,\"cost\":0.0002014,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":320,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000544,\"upstream_inference_completions_cost\":0.000147},\"completion_tokens_details\":{\"reasoning_tokens\":74,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 551.782167ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/multi_tool_streaming.yaml
new file mode 100644
index 000000000..75898eec7
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/multi_tool_streaming.yaml
@@ -0,0 +1,203 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 888
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"x-ai/grok-code-fast-1","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"The","reasoning_details":[{"type":"reasoning.summary","summary":"The","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.summary","summary":" user","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" asked","reasoning_details":[{"type":"reasoning.summary","summary":" asked","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.summary","summary":" to","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" add","reasoning_details":[{"type":"reasoning.summary","summary":" add","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.summary","summary":" and","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" multiply","reasoning_details":[{"type":"reasoning.summary","summary":" multiply","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.summary","summary":" ","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"2","reasoning_details":[{"type":"reasoning.summary","summary":"2","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.summary","summary":" and","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.summary","summary":" ","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"3","reasoning_details":[{"type":"reasoning.summary","summary":"3","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" need","reasoning_details":[{"type":"reasoning.summary","summary":" need","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.summary","summary":" to","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" use","reasoning_details":[{"type":"reasoning.summary","summary":" use","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" both","reasoning_details":[{"type":"reasoning.summary","summary":" both","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" add","reasoning_details":[{"type":"reasoning.summary","summary":" add","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.summary","summary":" and","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" multiply","reasoning_details":[{"type":"reasoning.summary","summary":" multiply","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" tools","reasoning_details":[{"type":"reasoning.summary","summary":" tools","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" at","reasoning_details":[{"type":"reasoning.summary","summary":" at","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" same","reasoning_details":[{"type":"reasoning.summary","summary":" same","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" time","reasoning_details":[{"type":"reasoning.summary","summary":" time","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".\n","reasoning_details":[{"type":"reasoning.summary","summary":".\n","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\n\n## Interpreting user request \n- The user wants to add and multiply the numbers 2 and 3 using both operations.","reasoning_details":[{"type":"reasoning.summary","summary":"\n\n## Interpreting user request \n- The user wants to add and multiply the numbers 2 and 3 using both operations.","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \n- The task requires handling both addition and multiplication in a single response.","reasoning_details":[{"type":"reasoning.summary","summary":" \n- The task requires handling both addition and multiplication in a single response.","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.encrypted","data":"cGl8lhSXiOt1MYGQgIDMy5UaCrMCywHWoiDI6mk0ECjZ9uP9YP1JRTINsHZzjqF4ZAAnmwB3/janVOxdFPWcbnDc85d5uHszu0+42lV0dJLBgt75ihLkWVMysxpa5vDi5Y5Kaob9gsykmWsDYAtFUBDOZqFeI1j/MoMMbSNM6ciCJz5NZlUjQKWuETE2XJBChCaymYHPL0xrDU+QcdPsO+zygzxWaeXRtBwUVEV9nMvMNV4ZK/kPPd5cqNGxV7xXhwqaaxp2ILyORO94Mzctbz429mLkxm2DiUq7RA5u0Lq+UisbBHsmPxxSFs6panamtDB4zPvFik8QqMaF9/WcZyfngdgTNm/VDTpI6v2lPJSZKDQXPLYCrLTn0iKtMjZBz8cnzkfcTwrtyu2OFwPhX4h9o319dOkU7AcTL9D/2ux4P2ovXmkArrsedb6oTTbNJMwNmFmrXtU1bE5VWLOtt8jEC9DzT2+8WK65MU+FJp7VQdA6o7qu+kXFjJG6W2vPKyjzHfNBYT5fgfmftvkS8NORfFfKLWJ76BgmMbythd4i1zMV3doL9P3IpS5lZrCc2xCfawvRywzNWlnCH5pStqxXTDQrnuF6tj1wnUHZME5ktKghNQW5/lLiU42+O2jFfAKciUIAYyOkpdY3qh5u48y7/wLueCZK+fxxBOX8oI+Op26Dn/HwS6LBlgcg5MHepAKDQPJsrvckNjGp/N2gvjUArQT4I9oOAoY3SNRnCM/jwy6E5QVvvjJmXHWHn7yuK3bbFKNhgc3DadA1pWxK+6ki7I7EAeUE7he8h5GD2N6moqMf4g7/My+Pk8wEBi2PIsBckJauWyXPVFSLyn7xKRd6XB7UfMXWG++mtLTR7ks/ZAVSbEmuRIMV2wPwCi5P4ofu0o9yJD1Hv+Y8+8YxEuJhsRkBvokw/hpoWkfrbDotpOn7HZQPWrDUlfyr/DTzf3xGU4xG4Cfc5sC3kO5mRmgk3FJo9MejfaUOyDorC5E+anuAzidaSiun0OzVguaD74+UHwNeUGKb/XKSUbQeRrz//3x9cvFdHU105A9TJHc4GwN4170bowTfvItDUzL6+5H+SrlKgNx+8cvOtPM7QcWTDLj5LRWDTHJYMo5qcAAsS9uKaP4hQEOT34D7iTlC2p8BgoLSFHknI2CKQSo7mn+Bipx6mahHz/6HX8vMouGiXTlEEOjJfdW1u96ku2Zuu8RII2r0tZqHjc4hNgudVqv84vZEmKZKy98cRrUux/Gx4pca3bXpc4VwC20mB2f+gTJjPGCduSCQYYOzphw9iRLo3tTQMAg0IEFauoX/Tlkn1BYy","id":"rs_76ad99b1-8eec-df8b-3a3a-5e5d65c7faa1_us-east-1","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"call_03955341","index":0,"type":"function","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"call_95368301","index":1,"type":"function","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"tool_calls","native_finish_reason":"completed","logprobs":null}]}
+
+ data: {"id":"gen-1761054146-TJznqBdTapU8K7vXSLVs","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054146,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":475,"completion_tokens":290,"total_tokens":765,"cost":0.0004724,"is_byok":false,"prompt_tokens_details":{"cached_tokens":320,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000374,"upstream_inference_completions_cost":0.000435},"completion_tokens_details":{"reasoning_tokens":222,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 694.5735ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1643
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_03955341","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"call_95368301","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"unknown","index":0,"text":"The user asked to add and multiply 2 and 3. I need to use both add and multiply tools at the same time.\n\n\n## Interpreting user request \n- The user wants to add and multiply the numbers 2 and 3 using both operations. \n- The task requires handling both addition and multiplication in a single response.","type":"reasoning.text"}]},{"content":"5","tool_call_id":"call_03955341","role":"tool"},{"content":"6","tool_call_id":"call_95368301","role":"tool"}],"model":"x-ai/grok-code-fast-1","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"I","reasoning_details":[{"type":"reasoning.summary","summary":"I","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" have","reasoning_details":[{"type":"reasoning.summary","summary":" have","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" results","reasoning_details":[{"type":"reasoning.summary","summary":" results","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":":","reasoning_details":[{"type":"reasoning.summary","summary":":","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" add","reasoning_details":[{"type":"reasoning.summary","summary":" add","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" gave","reasoning_details":[{"type":"reasoning.summary","summary":" gave","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.summary","summary":" ","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"5","reasoning_details":[{"type":"reasoning.summary","summary":"5","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" multiply","reasoning_details":[{"type":"reasoning.summary","summary":" multiply","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" gave","reasoning_details":[{"type":"reasoning.summary","summary":" gave","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.summary","summary":" ","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"6","reasoning_details":[{"type":"reasoning.summary","summary":"6","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".\n","reasoning_details":[{"type":"reasoning.summary","summary":".\n","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.encrypted","data":"AFPTbME2At55JwGnp66prJbrMHYPiUJDnchDVWvLE/CaN95V9X2YIDvX4l579PttFeRQZ3ZGnoOUmVc1hFaksP8h9AzALmYtC8le9n+xb5GD/VlIxNu7Y5tJipYIbvFwxZaoZoLQVHcvasW1Y1UqQ4Nv76KhtDQ4LakRY5hV3jpAdwwYCX+FsJcu0PaQ/m1wqL8ChBMgZMNApUMoQ3zGou4OUjvFLpP2eqg3yW2+WUPepKIAwltLc89S4jC8FB1VugtMAQS5HV6KBDU9c40dfyDpiyFWvQVQLnowZeKuN6vTV7h5MGwzFNfZJaGIX+dsDiJdGzDZPSEmxE0E3OetCr7E/4QdHjfWUbOfsrBAIsLJzQ","id":"rs_a2f68867-fef0-30a7-2364-9eb1cd0c3690_us-east-1","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"2"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":" +"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"3"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":" ="},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"5"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n\n"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"2"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":" *"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"3"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":" ="},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":"6"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"completed","logprobs":null}]}
+
+ data: {"id":"gen-1761054152-YYZUH6VDckQzLikTXyIP","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054152,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":556,"completion_tokens":77,"total_tokens":633,"cost":0.0001691,"is_byok":false,"prompt_tokens_details":{"cached_tokens":320,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000536,"upstream_inference_completions_cost":0.0001155},"completion_tokens_details":{"reasoning_tokens":62,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 683.774625ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/simple.yaml
new file mode 100644
index 000000000..b4032fcc3
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 196
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"x-ai/grok-code-fast-1","max_tokens":4000,"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054116-RmAaRVVL0OjqPdSqcv8v\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion\",\"created\":1761054116,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"completed\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"Oi! (That's \\\"hi\\\" in Portuguese.)\",\"refusal\":null,\"reasoning\":\"First, the user's query is \\\"Say hi in Portuguese.\\\" This is a simple, casual request. It's not a closed-ended science, math, or search question, but more of an open-ended or conversational one.\\n\\n\\n## Interpreting the Query \\n- The user's request is \\\"Say hi in Portuguese,\\\" a casual and conversational prompt. \\n- It's an open-ended question, not tied to science, math, or search, focusing on language and greeting.\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"First, the user's query is \\\"Say hi in Portuguese.\\\" This is a simple, casual request. It's not a closed-ended science, math, or search question, but more of an open-ended or conversational one.\\n\\n\\n## Interpreting the Query \\n- The user's request is \\\"Say hi in Portuguese,\\\" a casual and conversational prompt. \\n- It's an open-ended question, not tied to science, math, or search, focusing on language and greeting.\",\"format\":\"xai-responses-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"Xf9DtlVKCMysuTpyBQ7CHyfooPC19y8XxXQGEObwn5cg3Z/a9+aAvjeAfeSY52C6aaUuwy77eZjGF4T0UAbl2u6U5VfBYBOQ5UaeItOd3DPePzcBdUtNwicC4z/4HHRkjNtvNduG/4z7r14eKckh5hkr8nivotcaVCnZTIseQMX5nEwomvLRYDSVbFz5S0qGMC6V0bI+hcpwnR192gz9b4c6i32lewzKx3VXMXcmn1gdBGk4HsJInRRAWZRYqnoS0BG6Ss4Cgbnqgn7LSj3f2ACDfhU/ZrcYOlzCz97wxUzxWuVfmV4/j0DajhVWb8SRfRhX88d+trgfltGQ0E3+iGGsJoYPhkRo+HtSgfzEOA7Gjk4n+QhfbUSG4IJnVr3fnIldrpUvG2BAbT6Yrwv5yyZRZJPIucBmzxEIEeC8uqiwA2G8SRrsifF7y51nL0MBqgbwi5yEALA4juadGA7y4a7JXYwqt5iYZHo83vcj1AFZmjogdoh9iqFoDjcMeDKMoOwbANvu/NmV9QLHwfbIss0+cZ3zBwVp4cGq487f57Mop8ZnK3xeq2QrhTtGlaggvczWnG0AFIEJRjoA3OaumQFCTcC1yV5om71KgbLO1S8Nm4szSgHiAtSnQhdpznw2W3KxlSQ4sUn4eksIX9DOTvCV3zW8yxJzVo2vMs09GA8VuKG1g8XSNzsXnZyE2LpvFDq2ltvO5p7rxeyNaXwUgUQ7uAMA38CZ6JQSUtTC2bTDtmZeV7qCTd+OR8ruDhWYEKDN1UYikFtzB0dJ9IM/bp2NaTWJv4UuoS17L3rQb1Tagm8FIPOyxPogCKlxV17StvOJetcuG8ivweWDoGDNeZqKSStCBjPDVoM1Ic+HwQHx2ov4eBclFX1NGXkUUfQv3TLvtFfUuXA1kyEZQ8+aXOuFW7HGMxkJetQ/Y5EKw3BPIxsfoVg2PeW2MI7/QakwPz0gmxpmEESuPi7h4F7999HGYwU4o//xjtFA9KFgDSgOV8U5i3HpUUQtHBzFQGJ6tP57sbnAgtvSJ7YNyNjeoLYdNcqfPGkyME5gn9nX6bPCJKCxYSB/8BxlRv9UvRKkrrgQPW9F9qOo9DHeZ79UmWl8I/L82ASHug9TFqDhwz5tWhe619JO6haMWTR0C2uIwrgSWvfZ6tNdH4IdjhtEMxFSANBPNSOWBuWGZEJDhMeg4h9WS2566/J10PCAWXzaZ6vCa7o2mYN80LsF95mLaeizn3u8Etzz9hpw9ZaO6cXUFj4m0KN86dIBOaY+FGbxltR5L2SLdY1zK9/z4oS5eKaKP9FUlSVXVxueu0y/IvEK0lgfe+Wp42zVLxYjf902StA5F45dxqs42u/B2bxOnSGpq7kd6pqghxfXZax5NaxFB0NYG2OEz7e5wADPaQir1Pn3pth7lq4/\",\"id\":\"rs_66bf7ee5-6780-5aad-3399-62114b35af11_us-east-1\",\"format\":\"xai-responses-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":213,\"completion_tokens\":238,\"total_tokens\":451,\"cost\":0.00036504,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":192,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00000804,\"upstream_inference_completions_cost\":0.000357},\"completion_tokens_details\":{\"reasoning_tokens\":228,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 682.839459ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/simple_streaming.yaml
new file mode 100644
index 000000000..20b181063
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/simple_streaming.yaml
@@ -0,0 +1,32 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 250
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"x-ai/grok-code-fast-1","max_tokens":4000,"stream_options":{"include_usage":true},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: "data: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\"First\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"First\",\"format\":\"xai-responses-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\",\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\",\",\"format\":\"xai-responses-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\" the\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\" the\",\"format\":\"xai-responses-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\" user\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\" user\",\"format\":\"xai-responses-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\" said\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\" said\",\"format\":\"xai-responses-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\":\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\":\",\"format\":\"xai-responses-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\" \\\"\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\" \\\"\",\"format\":\"xai-responses-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\"Say\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"Say\",\"format\":\"xai-responses-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\" hi\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\" hi\",\"format\":\"xai-responses-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\" in\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\" in\",\"format\":\"xai-responses-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\" Portuguese\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\" Portuguese\",\"format\":\"xai-responses-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\"\\\"\\n\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"\\\"\\n\",\"format\":\"xai-responses-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\"\\n\\n## Handling greeting request \\n- The user asked for a greeting in Portuguese, specifically \\\"hi.\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"\\n\\n## Handling greeting request \\n- The user asked for a greeting in Portuguese, specifically \\\"hi.\",\"format\":\"xai-responses-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"reasoning\":null,\"reasoning_details\":[{\"type\":\"reasoning.encrypted\",\"data\":\"IGhtx1uXZlmIHNa841650McAFWCLEw7OA0J4W1kdEh+h9EiUs5lhs05/g0eGoQt3CCBnHW+tQNmUOpnw3/cL4tLuPUYarcJowP48ymg9YUfjALKT+CzIYAm7CS9D8ANg8nDUnRNTqo0PxQ79FkohdYYb3p5kvU5pbwUP9DpnrC0Sp15vy5Xx7NXodqpHwU8yxOboLkz+My9Sy9+4WC1zms5fpLLmBNcffY3XSX4ZRVKTYSO8d8/Io2ToM07kA4HMx3JXLcVU1MuBWf7ABeN9zoxngk2mjn5Qb4F/qSPn+L2q3JkwYXQ0ikCHa3QS9siGQZ0vcbyAiQ4E2MeskMiCeE7ecIJWszohWzb/umdLb5R30EZpNUMFtYi51hhr/TxoUE8xP26+5a0+JSmSMtnBWf4DL6XkLFU5+KAYjTUVJbV6zg9YfxydmRiVb1kiUA3c/uLANIxOr4/SZRHWyj+oXNL1Mcjsn3OqX25+vv/ydiZQNiZG1JeQp7+yw0AizJM5hpklPq7YmMjW6hYJpPn7vWKCYhYfeSo+nfBmBNOqjiFnmJYBgfERPzlbDiLBYxZJoIndZ1qg3/QziFxMi8Kxq03/4+PVbbcmgvV0E64W2JwWbQS4L9Fg5DbZzxhAnBxVQlv4YwPu1HTmjRzVzYW2NCmavF3BJEpGvkyhouJrOxASJw8ppMBrCRoJ8ax5b5nOAk7BfcSKAYvKn61S5+3vldDoxCVfsoYHZzuPRIDUFMiEN2WFAf0xzHkUeutj3sH4jOOg+/vco6o93KbWXxHs5fu5KHTFYTbpawEOwb1PcOzzvPnTlkICd8z/MnUJevBdNlpCsney/63RUW3AAWWPjezYDWRMIOEl56D5uAfJ4H01S5yI0zdonCaFJkbMB1Q3qy6TjAD3xW063jP9G3bpTwh7HyXpsEtlxsaV2jB2qjsIdj5KFNVgJBqY1LvZ1taA0E4oXnlCo7/zH48iWzCwNLJIBI2ZQFTythTamoZNDKZ/gPn0EQ0WoP2O1MqOUjPPyujKLyMMPfRJE0n9Aw\",\"id\":\"rs_238277c7-d1ef-f754-58f2-c4754b09c654_us-east-1\",\"format\":\"xai-responses-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"Oi\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"!\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\" (\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"That\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\" means\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\" \\\"\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"hi\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\\\"\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\" in\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\" Portuguese\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\".)\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\" If\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\" you\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\" meant\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\" a\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\" more\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\" formal\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\" greeting\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\",\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\" it's\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\" Ol\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"Ć”\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\".\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\" \"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\U0001F60A\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\"},\"finish_reason\":\"stop\",\"native_finish_reason\":\"completed\",\"logprobs\":null}]}\n\ndata: {\"id\":\"gen-1761054121-OXqnDXqojajNzEWdaMoR\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion.chunk\",\"created\":1761054121,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\"},\"finish_reason\":null,\"native_finish_reason\":null,\"logprobs\":null}],\"usage\":{\"prompt_tokens\":213,\"completion_tokens\":194,\"total_tokens\":407,\"cost\":0.00029904,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":192,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00000804,\"upstream_inference_completions_cost\":0.000291},\"completion_tokens_details\":{\"reasoning_tokens\":169,\"image_tokens\":0}}}\n\ndata: [DONE]\n\n"
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 227.5025ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/tool.yaml
new file mode 100644
index 000000000..0c2b654f7
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 488
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"x-ai/grok-code-fast-1","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054124-oLsdSux366LQUlPXZ03d\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion\",\"created\":1761054124,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"completed\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":\"First, the user asked about the weather in Florence, Italy. I have a tool called \\\"weather\\\" that can get weather information for a location.\\n\",\"tool_calls\":[{\"id\":\"call_92800071\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\":\\\"Florence,Italy\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"First, the user asked about the weather in Florence, Italy. I have a tool called \\\"weather\\\" that can get weather information for a location.\\n\",\"format\":\"xai-responses-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"gW/QTNM4EI4+f+O7qXC7JJmVjcOngbH/csPN/zlpCalEzGBjful1XVL5Hfz4pz/7IzcZn0UExUOy/svaHRz5vQDm6aWjWY9jeIOJF6KnSPbIEeb0EfT8+HVBcJSv3ICdE79OQrzieXm0aCje7frovWcPgqWn6o7XL7znWkM5cdJpfeTJLXKEHtoPamoi5nIfDfPLQxsGvewkOHkV1buSgYzYO8LDtWD+WOjk1GLxjfBFLv1cePVOH5Nyct8UbWECZPaneuQbLk/AELwaM/J+qMyZM2aJ7M4irvOtLZ1L7Aaoakr3bgKdzZcJ9YS/D+Bmk2AnQcM37ewUMuFaYP3nFkurzUiR8swUNpEUQyfzzYxMrW8puQ5Jc2WX0pZxFU+Y8BFk+7FrPI1ekKjtdzBW6bsKRmANIu5a8kw5mNN/pWTbMekO56dtJ7zMUuxoq/tMfvYoNalh0U3nWCeuHFH6exM5DgOn4tWVgKv/NWMQzOekjcz7zckIOuqsARsLALEVjeF2ypkfmExfBbj36paYJZehU6BgK/MpGeuvGPE2Lpc99NTDseCkGbpfyBtFzFro8cZGXe/kDEMFUSxXRmPCfVDs4wB2k5fbdUAar5yU1Z6Il2a0HtybHTgFSN7xwaZ0IKItymDaVfdKb16sHUxu4h6tTNtdiSq17wVs27UdWWnTlsi0skbhR6wUfZkfE+XtV+IruXuW4Iif/EfChIt+JPgWdCkhAXNZqeTIBn2HH56qI3iAsXT8gA1EeF8igqy0Qk4xPts41RCsIANSgikStt8/p5PV8Ie7EI1ylSgeznKdksH9BGo\",\"id\":\"rs_ed6e5f4a-92ad-6e74-2eff-7284f5d073a3_us-east-1\",\"format\":\"xai-responses-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":394,\"completion_tokens\":153,\"total_tokens\":547,\"cost\":0.0002507,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":320,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000212,\"upstream_inference_completions_cost\":0.0002295},\"completion_tokens_details\":{\"reasoning_tokens\":127,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 470.70975ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 937
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_92800071","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"unknown","index":0,"text":"First, the user asked about the weather in Florence, Italy. I have a tool called \"weather\" that can get weather information for a location.\n","type":"reasoning.text"}]},{"content":"40 C","tool_call_id":"call_92800071","role":"tool"}],"model":"x-ai/grok-code-fast-1","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054134-8YJtdv8QtokjObI4aR6V\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion\",\"created\":1761054134,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"completed\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The weather in Florence, Italy is currently 40°C. If you need more details or a forecast, let me know!\",\"refusal\":null,\"reasoning\":\"First, the user asked for the weather in Florence, Italy. I used the weather tool, and the function returned \\\"40 C\\\", which I believe means 40 degrees Celsius.\\n\\n\\n## Checking Weather Request \\n- The user asked for the weather in Florence, Italy.\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"First, the user asked for the weather in Florence, Italy. I used the weather tool, and the function returned \\\"40 C\\\", which I believe means 40 degrees Celsius.\\n\\n\\n## Checking Weather Request \\n- The user asked for the weather in Florence, Italy.\",\"format\":\"xai-responses-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"CJBw6QcFTIVsAhYESlP0tNH9DAz8m+BBN+w+F423qMTwBePXdCFmTj0VoWklVdNDbR09ns1dYB+mnJEUNn4GQRf04hmidn74HdbI0yw8W3HVk8nOX3/6FB/hA/DqGQ1svrDE3sJ3UEwNPDXXshnUxDUd5khkO/dbOtx7t/JifdaTS2CgnzBzEgKZRq4jSxrmeL4ofIqQzJp6ZW/Na4w2KmF355RNKcMFqHbEk0+5vu161u7lsLvcfGDHmMTuSwiQwaECqg/nPeNXDiXTp7Jq3eyHkVxnC2s4LpzToerW9/BmlHhTkY9TmkSM7sBSgNkSbCUh8/J/9sey/JBAtQ8YacbIRva08tgQWDxFO1ckc8pIFpwQY35YwjYk5oO65y3EpjIr8lXfd/6t2Uy56cxGUEohq4qQaTZ3IqdRMeUY1SgViBuRsr9ItMK2O5Rk0rX1UOg7ImISzx8vikxmpjwqcz3XI6gYU+P4akz63NWU8SVKC/Z077b93cMJeVDbot/e/ZE+eOs8uvi0e00rbj76jdoBt53aCu2AFg2UNeZOHNUhwhCLQc2AW2s2fDLUKu1kDXvfbAPGxRvUKIoWS3Cbt/iWzE7FN9SZq6klEZKX/CiHyRwqekfcNd6Xq2bitBzgVYztJO0raZaek7SlSZXJpAd6msg0b55zt9T9SnVnKO+cpjvvNovaBJxQ+qpUXnTgzCeaBfEEmvjmtHB9iPKSCFQRsNTzTl8SxT4HzlPNHLGAM4JaUfR2gUSLA0lvxmEEUJvXbFGriFrloLPGes4JrW7sJPfuTYnlBCKzTSK9Im18YSOCtKF+hyxVXnEauTvlYka6MokWNcNt/6DumL0iNQccXFJNHBa7oLpgBe+2twHPOJyHvOh14bewuT6KMSFbz8dFD0KKXaUQF7ZCDa7T4Ozdjf/yxLNc6IxaY3+9EuassB2RzwzLW8pZnTnCod+M5o5j82pFiq6vMJHbCgb7gRpTEvOhOQmUernomz0eBgbxLd3CO/gvc7zmr0PntK6/KS99p4IXIZJ8d4tL0fr3MoSwyW6gIPj2bPJpyhU2dKrm9Cnh0YVBE2QKy69I3SS6lBJIWCNE+2ES3MicyGZJ3eKBlQiaJvq1xCyyBvqtN5saL+lwsdyWVJz9/kVJg16Ge+iV3RHw3ZlzwabQUM5z6xU5wompN0yS1jRsjv6eRQVh2HwEspxI9DI7kNB/ko4OYjRAcMEcSUJdpwmMV180JLCu8P16XWD+fY3S1K2/dvBvoJy7+Vq8XBhMRDzdZCdV9H/M9nrNqYhXulJp7s0pNK2HtkYAQk53FQenVrMfWhMIP5yAqyVDoSf9/2Gu5Nz1WmhLsU0BS0Pf5gD+mNbPfsC/WMcUo9lSLvuPthq3IKRXSi4DSlRAqFDsYIsvtokT0IvMsgGMoLvf1SOr2jIH/et6TfLOQIILdLKpgvHtcZ1MpyEmvZCddtV3YDgv1zUJZ4xexaYtv31RvE1sLLiiZAsl1PtE0e7m3ieTTFrpob2WwT40rc32AfUANgjdfqoYd8Vgw5B9NI7ZXdwUi3ckTW9Rn1c\",\"id\":\"rs_f90cd679-c9ea-0b3f-65c0-6b6ef4c939b9_us-east-1\",\"format\":\"xai-responses-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":432,\"completion_tokens\":276,\"total_tokens\":708,\"cost\":0.0004428,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":320,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000288,\"upstream_inference_completions_cost\":0.000414},\"completion_tokens_details\":{\"reasoning_tokens\":251,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 569.763458ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/tool_streaming.yaml
new file mode 100644
index 000000000..d4bff4460
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/grok-code-fast-1/tool_streaming.yaml
@@ -0,0 +1,235 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 542
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"x-ai/grok-code-fast-1","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"The","reasoning_details":[{"type":"reasoning.summary","summary":"The","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.summary","summary":" user","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" asked","reasoning_details":[{"type":"reasoning.summary","summary":" asked","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":":","reasoning_details":[{"type":"reasoning.summary","summary":":","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.summary","summary":" \"","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"What's","reasoning_details":[{"type":"reasoning.summary","summary":"What's","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.summary","summary":" weather","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" in","reasoning_details":[{"type":"reasoning.summary","summary":" in","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.summary","summary":" Florence","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Italy","reasoning_details":[{"type":"reasoning.summary","summary":"Italy","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"?\"\n","reasoning_details":[{"type":"reasoning.summary","summary":"?\"\n","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.encrypted","data":"dY1gp6hwdKnd1Xb6Hwnn+noy9dmU552HLB8ZOvsX7ylLDK+C4z85wvrNg7mElDtfIxVvR647W03hbOSxZCfak+8JeD4F8Noqzgr1K+GHEcc3WTGY3wtWk0Vf0vZWpQnMTlhieqlT0rwHlVCrvNSFCS/lENo7hz90l7/K3hT2IzaeNR7hB7bPjAvYc+PaPZjDqV5L44xEgUDdsuEM54Wyf9an2zn3oJnLOYSORCPX5IC/AWGpB1p+ZB445A0Epf1p6yuXjshYwwkZLOrDM05Z6Jua+sOnWQRH/4X/BWDus5EWzpS4IGwHPfn0lpM6VIKf4NI8DnzttqQeEADVTzk9MxOtOCvle+6f1LlwghW7w4Dxt8hCfGzSRQCdRt+LS5R3i909n9I1tjdYZrOidiLRVG5BC3XcRFP/z2SXGkDkFv1jLSVpDcJpfIXGQWrCQNf1vabnaIc76LXcImcP9FU7haM3tFm32OAPcOX9UG3Uq+8VsGWZb/nZ/OemdllH2hbmz4P1eWaowl8b6y9aywlw+sgw0FGq5Ytc9w3smzSc4e8eD2Jg1wiMBnQjQnzQGxwHKVtlHngxWfuHiJ1IzwfkHWMed6tXAYdiNrKI6y9BfW+Z20UX80fZztt4hyAbWTtlQ4sZ+q5FgD8En9YgjnOnBrdls8Rd4TGzx1mRP1D9WLcnhUSgnUShfv1XAfH2IIXUZKeAcA61h2KIqsMS919eC5/JmAL7Rgu+kSzfYJRa4OzD4qPXvHZCOvrdZ8GZ8LjpeyPoEpgQeU9K+M4hIM6neUs6wwwB4rI+FZoBK5bQ9BkKB+k9","id":"rs_4071253c-6f1c-0bab-f8bb-1e04c08c32c5_us-east-1","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"call_05843780","index":0,"type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence,Italy\"}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"tool_calls","native_finish_reason":"completed","logprobs":null}]}
+
+ data: {"id":"gen-1761054137-Y2KVAJHkgtOf0Sk7OeiA","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054137,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":394,"completion_tokens":159,"total_tokens":553,"cost":0.00024818,"is_byok":false,"prompt_tokens_details":{"cached_tokens":384,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00000968,"upstream_inference_completions_cost":0.0002385},"completion_tokens_details":{"reasoning_tokens":133,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 231.2955ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 907
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_05843780","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"unknown","index":0,"text":"The user asked: \"What''s the weather in Florence,Italy?\"\n","type":"reasoning.text"}]},{"content":"40 C","tool_call_id":"call_05843780","role":"tool"}],"model":"x-ai/grok-code-fast-1","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"First","reasoning_details":[{"type":"reasoning.summary","summary":"First","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.summary","summary":" user","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" asked","reasoning_details":[{"type":"reasoning.summary","summary":" asked","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.summary","summary":" for","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.summary","summary":" weather","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" in","reasoning_details":[{"type":"reasoning.summary","summary":" in","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.summary","summary":" Florence","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Italy","reasoning_details":[{"type":"reasoning.summary","summary":" Italy","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" used","reasoning_details":[{"type":"reasoning.summary","summary":" used","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.summary","summary":" weather","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" tool","reasoning_details":[{"type":"reasoning.summary","summary":" tool","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" which","reasoning_details":[{"type":"reasoning.summary","summary":" which","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" returned","reasoning_details":[{"type":"reasoning.summary","summary":" returned","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.summary","summary":" \"","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"40","reasoning_details":[{"type":"reasoning.summary","summary":"40","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" C","reasoning_details":[{"type":"reasoning.summary","summary":" C","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\".","reasoning_details":[{"type":"reasoning.summary","summary":"\".","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" That","reasoning_details":[{"type":"reasoning.summary","summary":" That","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" seems","reasoning_details":[{"type":"reasoning.summary","summary":" seems","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" like","reasoning_details":[{"type":"reasoning.summary","summary":" like","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.summary","summary":" a","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" temperature","reasoning_details":[{"type":"reasoning.summary","summary":" temperature","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" probably","reasoning_details":[{"type":"reasoning.summary","summary":" probably","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.summary","summary":" ","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"40","reasoning_details":[{"type":"reasoning.summary","summary":"40","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" degrees","reasoning_details":[{"type":"reasoning.summary","summary":" degrees","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Celsius","reasoning_details":[{"type":"reasoning.summary","summary":" Celsius","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".\n","reasoning_details":[{"type":"reasoning.summary","summary":".\n","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\n\n## Handling Weather Inquiry \n- The user requested the current weather in Florence, Italy.","reasoning_details":[{"type":"reasoning.summary","summary":"\n\n## Handling Weather Inquiry \n- The user requested the current weather in Florence, Italy.","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \n- The temperature was found to be 40°C, providing a key detail for the response.","reasoning_details":[{"type":"reasoning.summary","summary":" \n- The temperature was found to be 40°C, providing a key detail for the response.","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.encrypted","data":"qjIe/sCPewHyaT0H+IlJHI8k9z074vwbwP0sAfp202vfvGtR5SUPHz3PGqbKn5hUQadq+CMF2OHQm7+mGXTSTO6Kfbz0iLZNLoB352np4nZ11VQMCDPQK30Apxs9kfISvj7TBITiAzFTFBUGEo9u6/spBCXPOgghZmvskzY65PQ4BBBBk5Fm69xLemEwV+XkQHXTwF1sR4fPEkIQwUTv5J0cj4BIH9k2eoYjr+sEArldgMW7sFUjfOU3yAe3OdY0ltHL0+9dweH8K5a1tUPmmreKETHsDtw+5fwUhJvqGf1i4QnMrjZQlVHMhqs4LN+XV3SD+OH36lB4BTbL4rJ32oaccz9droGv7btcrarIJaJqOOyWeBfxnutOUWU4nhT26FkMZhHJLnWU7xqtUDWDLivYRCYLVrBA9BvvBJJajMoMeIRoI09M6aCwwOMhzup7WDdPLQq2x7yR79A+/7QrvOz4IE960baQxo6bDOy4dD8H5F8Bkg82DlHo8w7HruGXXKW01Z1vE8iUunPLKfPa0HFprHnJnHzX1280vkOTiPEm5rjx80TiSToFCWpYZ2GUeI4iKa7CRZ1EbrrGILQR+U+ULoTpsbAON+TWpGd/pyis/yQUZix3XOgF4ULjXqqRpBlzVu85VqvpqjTTks/UZS/fZ8EuiNn2MqXmYeLlHx73hfUP99A/SPr52/thKHVlQWVDcmkFflTTJVzupB4yiobqJLvnBDuDWyuAk0IN3hVYSDYAJjCQ8YPNkmsMiEMTDSZ/KCNaDBW9lq3SjtOQyZ9x52L8toB1g87kcUhZP+/je3FBoQaCe6V0R6MZzru5QGiNlWjZDhuBPI9orspzqoWoFd2C5OR1Y01bMS3yAf6R8L2/I6A6XnDag4zhqLnRhSKLvHXp5imakDiFsXi8WSPhpNjXCftgE6AJyr5qkRJuvsI+ThYOZ1pjX4+h/769RL83ofX8mFKooMr9mIo//J5n8rPNshh62oDthGZCJiE9ulTzBgKv5tQ5KCaXbbMinkp/5CwBOrWJX6XfYHzdYQYSgAAjnH7ZHesEJIcgKK8Fiytg7urgK6jTGW0kEaX06ud3Jzk4nN0LnfUDyCUOtOu1yTd7utWUlj6a5PQW1pxAErN8Rj/3/YkLNC0PES5uDtVatFII5GWoIzamUc/TBaizu034Ke42nhKPAoZURSy8ay5uH7pa5VO0t5QXEzNmJCz4CCt61BC3YYIkljbON6Dedj7MWzyTqQfrONPpTU79IrHvSJsjSnVCTSVmSfFosfxR7s9OpFz72XT/iuMLij3MMhDFcdqzmmKqeK9eChPnC2NCG4qZBV+b0mdJlU+pIkDlwxXXA9UdW/giITnET8QiQJVSlWLvc2xO4cYHjKqjr17S9nQYERfw0mFxY0Oo3v+KjDFSU8v1HGTcac0dObE6GR14OWOU0LB14Hhxk6DHLdA3n/f8mpV0kT5psJoE9bHWI4izYU8bEBPwN9Ujq7Kc4P5xfYvhbwILV+TGMuON6CDCvAmQYM1eBSLnOxXTGYcnYG0+lQFtrqqQhyIA18wANrfVz+y+CX7suHD8/ttX/bmVmOiG1L3hxSmJpb3wzQ8bDNC1fq/ySzz8UrsjWJEZhYN2pyOvHnlChNWbSynSXHyDsi7ytPBvBLvvUAPoi7hL6oi5t/SOzZxFCm7aBHIdS9clQwYR16mi+Mjs443nsUZtNuQ3asvFkIgBsK6zFtEVmsrn+JdKzECe","id":"rs_9994c6f1-64b3-888f-d572-80e69663d0fe_us-east-1","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"The"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" current"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" temperature"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" in"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" Florence"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":","},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" Italy"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" is"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"40"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"°C"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"."},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" For"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" more"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" details"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" like"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" humidity"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" or"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" forecast"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":","},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" let"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" me"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":" know"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":"!"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"completed","logprobs":null}]}
+
+ data: {"id":"gen-1761054139-hewkcVBVU0Bl7zxdjuI9","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054139,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":432,"completion_tokens":303,"total_tokens":735,"cost":0.00047178,"is_byok":false,"prompt_tokens_details":{"cached_tokens":384,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00001728,"upstream_inference_completions_cost":0.0004545},"completion_tokens_details":{"reasoning_tokens":279,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 245.174083ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/multi_tool.yaml
new file mode 100644
index 000000000..2550b518c
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 853
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"moonshotai/kimi-k2-0905","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1758884830-zaGHbgLiY1LQM5ZOVLtN\",\"provider\":\"Chutes\",\"model\":\"moonshotai/kimi-k2-0905\",\"object\":\"chat.completion\",\"created\":1758884830,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"I'll add and multiply the numbers 2 and 3 for you.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"id\":\"functions.add:0\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"add\",\"arguments\":\"{\\\"a\\\": 2, \\\"b\\\": 3}\"}},{\"id\":\"functions.multiply:1\",\"index\":1,\"type\":\"function\",\"function\":{\"name\":\"multiply\",\"arguments\":\"{\\\"a\\\": 2, \\\"b\\\": 3}\"}}]}}],\"usage\":{\"prompt_tokens\":201,\"completion_tokens\":55,\"total_tokens\":256,\"cost\":0.00015998,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00007638,\"upstream_inference_completions_cost\":0.0000836},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.143856417s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1301
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"I''ll add and multiply the numbers 2 and 3 for you.","tool_calls":[{"id":"functions.add:0","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"functions.multiply:1","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"functions.add:0","role":"tool"},{"content":"6","tool_call_id":"functions.multiply:1","role":"tool"}],"model":"moonshotai/kimi-k2-0905","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1758884834-GInh4t6Aro9w3F9lkWTH\",\"provider\":\"SiliconFlow\",\"model\":\"moonshotai/kimi-k2-0905\",\"object\":\"chat.completion\",\"created\":1758884834,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The results are:\\n- 2 + 3 = 5\\n- 2 Ć 3 = 6\",\"refusal\":null,\"reasoning\":null}}],\"system_fingerprint\":\"\",\"usage\":{\"prompt_tokens\":310,\"completion_tokens\":23,\"total_tokens\":333,\"cost\":0.00023247,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0001798,\"upstream_inference_completions_cost\":0.00005267},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.290988792s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/multi_tool_streaming.yaml
new file mode 100644
index 000000000..b5ca43a0c
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/multi_tool_streaming.yaml
@@ -0,0 +1,221 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 890
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"moonshotai/kimi-k2-0905","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":"I'll"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":" use"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":" both"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":" the"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":" add"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":" and"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":" multiply"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":" functions"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":" for"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":" the"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":" numbers"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":"2"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":" and"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":"3"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":"."},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"functions.add:0","type":"function","function":{"name":"add","arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":null,"type":"function","function":{"arguments":"{\""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":null,"type":"function","function":{"arguments":"a"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":null,"type":"function","function":{"arguments":"\":"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":null,"type":"function","function":{"arguments":" "}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":null,"type":"function","function":{"arguments":"2"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":null,"type":"function","function":{"arguments":","}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":null,"type":"function","function":{"arguments":" \""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":null,"type":"function","function":{"arguments":"b"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":null,"type":"function","function":{"arguments":"\":"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":null,"type":"function","function":{"arguments":" "}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":null,"type":"function","function":{"arguments":"3"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":null,"type":"function","function":{"arguments":"}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"id":"functions.multiply:1","type":"function","function":{"name":"multiply","arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"id":null,"type":"function","function":{"arguments":"{\""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"id":null,"type":"function","function":{"arguments":"a"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"id":null,"type":"function","function":{"arguments":"\":"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"id":null,"type":"function","function":{"arguments":" "}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"id":null,"type":"function","function":{"arguments":"2"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"id":null,"type":"function","function":{"arguments":","}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"id":null,"type":"function","function":{"arguments":" \""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"id":null,"type":"function","function":{"arguments":"b"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"id":null,"type":"function","function":{"arguments":"\":"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"id":null,"type":"function","function":{"arguments":" "}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"id":null,"type":"function","function":{"arguments":"3"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"id":null,"type":"function","function":{"arguments":"}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884837-DAt3ZHwS4SqjS2Q9UlWc","provider":"SiliconFlow","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884837,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":216,"completion_tokens":57,"total_tokens":273,"cost":0.00025581,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00012528,"upstream_inference_completions_cost":0.00013053},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.16851625s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1357
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"I''ll use both the add and multiply functions for the numbers 2 and 3.","tool_calls":[{"id":"functions.add:0","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"functions.multiply:1","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"functions.add:0","role":"tool"},{"content":"6","tool_call_id":"functions.multiply:1","role":"tool"}],"model":"moonshotai/kimi-k2-0905","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":"The results"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":" are"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":":\n"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":"-"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":" **"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":"Addition"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":"**:"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":"2"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":" +"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":"3"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":" ="},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":"5"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":"-"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":" **"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":"Multi"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":"plication"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":"**:"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":"2"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":" Ć"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":"3"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":" ="},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":"6"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1758884843-D64xm6eEzt7g4zqab1LD","provider":"Fireworks","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884843,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":286,"completion_tokens":31,"total_tokens":317,"cost":0.0002491,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0001716,"upstream_inference_completions_cost":0.0000775},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.343893666s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/simple.yaml
new file mode 100644
index 000000000..fe03c210c
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 198
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"moonshotai/kimi-k2-0905","max_tokens":4000,"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n{\"id\":\"gen-1758884820-pkZ0QE8RXjFWCt2WTCzO\",\"provider\":\"AtlasCloud\",\"model\":\"moonshotai/kimi-k2-0905\",\"object\":\"chat.completion\",\"created\":1758884820,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"Oi!\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":21,\"completion_tokens\":3,\"total_tokens\":24,\"cost\":0.0000201,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000126,\"upstream_inference_completions_cost\":0.0000075},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 837.696958ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/simple_streaming.yaml
new file mode 100644
index 000000000..2ef410182
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/simple_streaming.yaml
@@ -0,0 +1,44 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 252
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"moonshotai/kimi-k2-0905","max_tokens":4000,"stream_options":{"include_usage":true},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884821-ZnikKLLwFu5NjO5AoIHG","provider":"BaseTen","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884821,"choices":[{"index":0,"delta":{"role":"assistant","content":"Ol"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1758884821-ZnikKLLwFu5NjO5AoIHG","provider":"BaseTen","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884821,"choices":[{"index":0,"delta":{"role":"assistant","content":"Ć”"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1758884821-ZnikKLLwFu5NjO5AoIHG","provider":"BaseTen","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884821,"choices":[{"index":0,"delta":{"role":"assistant","content":"!"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1758884821-ZnikKLLwFu5NjO5AoIHG","provider":"BaseTen","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884821,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}],"system_fingerprint":null}
+
+ data: {"id":"gen-1758884821-ZnikKLLwFu5NjO5AoIHG","provider":"BaseTen","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884821,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":21,"completion_tokens":4,"total_tokens":25,"cost":0.0000226,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000126,"upstream_inference_completions_cost":0.00001},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 553.728583ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/tool.yaml
new file mode 100644
index 000000000..2b96e2f62
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 490
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"moonshotai/kimi-k2-0905","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1758884821-Px8tA7GjWtgBYTRZpf87\",\"provider\":\"Novita\",\"model\":\"moonshotai/kimi-k2-0905\",\"object\":\"chat.completion\",\"created\":1758884821,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"index\":0,\"id\":\"weather:0\",\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\": \\\"Florence, Italy\\\"}\"}}]}}],\"system_fingerprint\":\"fpv0_ef28f882\",\"usage\":{\"prompt_tokens\":76,\"completion_tokens\":20,\"total_tokens\":96,\"cost\":0.0000956,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000456,\"upstream_inference_completions_cost\":0.00005},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.135107s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 703
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"weather:0","function":{"arguments":"{\"location\": \"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"weather:0","role":"tool"}],"model":"moonshotai/kimi-k2-0905","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1758884824-qRbc0CoGllBEAT33MPab\",\"provider\":\"SiliconFlow\",\"model\":\"moonshotai/kimi-k2-0905\",\"object\":\"chat.completion\",\"created\":1758884824,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"Currently, it's **40°C** in Florence, Italy.\",\"refusal\":null,\"reasoning\":null}}],\"system_fingerprint\":\"\",\"usage\":{\"prompt_tokens\":144,\"completion_tokens\":12,\"total_tokens\":156,\"cost\":0.000111,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00008352,\"upstream_inference_completions_cost\":0.00002748},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.805386959s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/tool_streaming.yaml
new file mode 100644
index 000000000..92e98f313
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/kimi-k2/tool_streaming.yaml
@@ -0,0 +1,163 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 544
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"moonshotai/kimi-k2-0905","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884826-U5ZJVEJjQ0uPyj8la9VS","provider":"Groq","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884826,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":"fp_6e6ff3688b"}
+
+ data: {"id":"gen-1758884826-U5ZJVEJjQ0uPyj8la9VS","provider":"Groq","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884826,"choices":[{"index":0,"delta":{"role":"assistant","content":"I'll"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":"fp_6e6ff3688b"}
+
+ data: {"id":"gen-1758884826-U5ZJVEJjQ0uPyj8la9VS","provider":"Groq","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884826,"choices":[{"index":0,"delta":{"role":"assistant","content":" check"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":"fp_6e6ff3688b"}
+
+ data: {"id":"gen-1758884826-U5ZJVEJjQ0uPyj8la9VS","provider":"Groq","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884826,"choices":[{"index":0,"delta":{"role":"assistant","content":" the"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":"fp_6e6ff3688b"}
+
+ data: {"id":"gen-1758884826-U5ZJVEJjQ0uPyj8la9VS","provider":"Groq","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884826,"choices":[{"index":0,"delta":{"role":"assistant","content":" weather"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":"fp_6e6ff3688b"}
+
+ data: {"id":"gen-1758884826-U5ZJVEJjQ0uPyj8la9VS","provider":"Groq","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884826,"choices":[{"index":0,"delta":{"role":"assistant","content":" in"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":"fp_6e6ff3688b"}
+
+ data: {"id":"gen-1758884826-U5ZJVEJjQ0uPyj8la9VS","provider":"Groq","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884826,"choices":[{"index":0,"delta":{"role":"assistant","content":" Florence"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":"fp_6e6ff3688b"}
+
+ data: {"id":"gen-1758884826-U5ZJVEJjQ0uPyj8la9VS","provider":"Groq","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884826,"choices":[{"index":0,"delta":{"role":"assistant","content":","},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":"fp_6e6ff3688b"}
+
+ data: {"id":"gen-1758884826-U5ZJVEJjQ0uPyj8la9VS","provider":"Groq","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884826,"choices":[{"index":0,"delta":{"role":"assistant","content":" Italy"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":"fp_6e6ff3688b"}
+
+ data: {"id":"gen-1758884826-U5ZJVEJjQ0uPyj8la9VS","provider":"Groq","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884826,"choices":[{"index":0,"delta":{"role":"assistant","content":" for"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":"fp_6e6ff3688b"}
+
+ data: {"id":"gen-1758884826-U5ZJVEJjQ0uPyj8la9VS","provider":"Groq","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884826,"choices":[{"index":0,"delta":{"role":"assistant","content":" you"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":"fp_6e6ff3688b"}
+
+ data: {"id":"gen-1758884826-U5ZJVEJjQ0uPyj8la9VS","provider":"Groq","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884826,"choices":[{"index":0,"delta":{"role":"assistant","content":"."},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":"fp_6e6ff3688b"}
+
+ data: {"id":"gen-1758884826-U5ZJVEJjQ0uPyj8la9VS","provider":"Groq","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884826,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"functions.weather:0","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence,Italy\"}"},"index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":"fp_6e6ff3688b"}
+
+ data: {"id":"gen-1758884826-U5ZJVEJjQ0uPyj8la9VS","provider":"Groq","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884826,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}],"system_fingerprint":"fp_6e6ff3688b"}
+
+ data: {"id":"gen-1758884826-U5ZJVEJjQ0uPyj8la9VS","provider":"Groq","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884826,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":99,"completion_tokens":32,"total_tokens":131,"cost":0.000195,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.000099,"upstream_inference_completions_cost":0.000096},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 269.997625ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 838
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"I''ll check the weather in Florence, Italy for you.","tool_calls":[{"id":"functions.weather:0","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"functions.weather:0","role":"tool"}],"model":"moonshotai/kimi-k2-0905","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":"The"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" weather"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" in"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" Florence"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":","},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" Italy"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" is"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" currently"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":"40"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":"°C"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" ("},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":"104"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":"°F"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":")."},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" That's"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" quite"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" hot"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":"!"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" Make"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" sure"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" to"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" stay"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" hydrated"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" and"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" seek"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" shade"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" if"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" you're"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":" there"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":"."},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1758884827-EroginRaI3kJZawhI1Do","provider":"Chutes","model":"moonshotai/kimi-k2-0905","object":"chat.completion.chunk","created":1758884827,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":147,"completion_tokens":32,"total_tokens":179,"cost":0.0001045,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00005586,"upstream_inference_completions_cost":0.00004864},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.314927417s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/multi_tool.yaml
new file mode 100644
index 000000000..d5cecd985
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 855
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"qwen/qwen3-235b-a22b-2507","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n{\"id\":\"gen-1758884951-GO3hw5WL6M8IVJradpNR\",\"provider\":\"Targon\",\"model\":\"qwen/qwen3-235b-a22b-2507\",\"object\":\"chat.completion\",\"created\":1758884951,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"id\":\"call_6ce3a9f1b90844948694dd11\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"add\",\"arguments\":\"{\\\"a\\\": 2, \\\"b\\\": 3}\"}},{\"id\":\"call_2b4bab739bbf4f90a4b39c5c\",\"index\":1,\"type\":\"function\",\"function\":{\"name\":\"multiply\",\"arguments\":\"{\\\"a\\\": 2, \\\"b\\\": 3}\"}}]}}],\"usage\":{\"prompt_tokens\":267,\"completion_tokens\":50,\"total_tokens\":317,\"cost\":0.00006154,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00003204,\"upstream_inference_completions_cost\":0.0000295},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.477123s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1286
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_6ce3a9f1b90844948694dd11","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"call_2b4bab739bbf4f90a4b39c5c","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"call_6ce3a9f1b90844948694dd11","role":"tool"},{"content":"6","tool_call_id":"call_2b4bab739bbf4f90a4b39c5c","role":"tool"}],"model":"qwen/qwen3-235b-a22b-2507","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n{\"id\":\"gen-1758884953-JfczI58B5pft34EVqDpe\",\"provider\":\"WandB\",\"model\":\"qwen/qwen3-235b-a22b-2507\",\"object\":\"chat.completion\",\"created\":1758884953,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The sum of 2 and 3 is 5, and the product of 2 and 3 is 6.\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":355,\"completion_tokens\":26,\"total_tokens\":381,\"cost\":0.0000381,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000355,\"upstream_inference_completions_cost\":0.0000026},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 652.308417ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/multi_tool_streaming.yaml
new file mode 100644
index 000000000..bd4d3c5bc
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/multi_tool_streaming.yaml
@@ -0,0 +1,133 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 892
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"qwen/qwen3-235b-a22b-2507","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884955-31m1LMcZtky2tb0PDQ4s","provider":"DeepInfra","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884955,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884955-31m1LMcZtky2tb0PDQ4s","provider":"DeepInfra","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884955,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"call_3e11","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884955-31m1LMcZtky2tb0PDQ4s","provider":"DeepInfra","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884955,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884955-31m1LMcZtky2tb0PDQ4s","provider":"DeepInfra","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884955,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"id":"call_e95d","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884955-31m1LMcZtky2tb0PDQ4s","provider":"DeepInfra","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884955,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}]}
+
+ data: {"id":"gen-1758884955-31m1LMcZtky2tb0PDQ4s","provider":"DeepInfra","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884955,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":273,"completion_tokens":49,"total_tokens":322,"cost":0.00005397,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00002457,"upstream_inference_completions_cost":0.0000294},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 892.076875ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1258
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"\n","tool_calls":[{"id":"call_3e11","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"call_e95d","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"call_3e11","role":"tool"},{"content":"6","tool_call_id":"call_e95d","role":"tool"}],"model":"qwen/qwen3-235b-a22b-2507","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":"The"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":" sum"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":" of"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":"2"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":" and"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":"3"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":" is"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":"5"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":","},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":" and"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":" the"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":" product"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":" of"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":"2"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":" and"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":"3"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":" is"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":"6"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":"."},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1758884957-vP0GT3mZMt6zqP4RWgEk","provider":"WandB","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884957,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":351,"completion_tokens":26,"total_tokens":377,"cost":0.0000377,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000351,"upstream_inference_completions_cost":0.0000026},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 298.753083ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/simple.yaml
new file mode 100644
index 000000000..5b01ef1db
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 200
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"qwen/qwen3-235b-a22b-2507","max_tokens":4000,"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n{\"id\":\"gen-1758884943-b00KqdyBPMoImmxC3fhs\",\"provider\":\"DeepInfra\",\"model\":\"qwen/qwen3-235b-a22b-2507\",\"object\":\"chat.completion\",\"created\":1758884943,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"OlĆ”!\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":22,\"completion_tokens\":3,\"total_tokens\":25,\"cost\":0.00000378,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00000198,\"upstream_inference_completions_cost\":0.0000018},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 777.175458ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/simple_streaming.yaml
new file mode 100644
index 000000000..8db7a0367
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/simple_streaming.yaml
@@ -0,0 +1,46 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 254
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"qwen/qwen3-235b-a22b-2507","max_tokens":4000,"stream_options":{"include_usage":true},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884944-mvxXvlojSq5gpwFfLLcj","provider":"Chutes","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884944,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884944-mvxXvlojSq5gpwFfLLcj","provider":"Chutes","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884944,"choices":[{"index":0,"delta":{"role":"assistant","content":"Ol"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884944-mvxXvlojSq5gpwFfLLcj","provider":"Chutes","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884944,"choices":[{"index":0,"delta":{"role":"assistant","content":"Ć”"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884944-mvxXvlojSq5gpwFfLLcj","provider":"Chutes","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884944,"choices":[{"index":0,"delta":{"role":"assistant","content":"!"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884944-mvxXvlojSq5gpwFfLLcj","provider":"Chutes","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884944,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1758884944-mvxXvlojSq5gpwFfLLcj","provider":"Chutes","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884944,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":22,"completion_tokens":4,"total_tokens":26,"cost":0.00000376,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000022,"upstream_inference_completions_cost":0.00000156},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 670.223833ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/tool.yaml
new file mode 100644
index 000000000..6000758c2
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 492
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"qwen/qwen3-235b-a22b-2507","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n{\"id\":\"gen-1758884945-5uDqMdZtpqK4kUPIuQIf\",\"provider\":\"WandB\",\"model\":\"qwen/qwen3-235b-a22b-2507\",\"object\":\"chat.completion\",\"created\":1758884945,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"id\":\"chatcmpl-tool-fd4d9460276d48b9ab949c0188d8cfae\",\"type\":\"function\",\"index\":0,\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\": \\\"Florence, Italy\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":171,\"completion_tokens\":22,\"total_tokens\":193,\"cost\":0.0000193,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000171,\"upstream_inference_completions_cost\":0.0000022},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 401.369ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 779
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"chatcmpl-tool-fd4d9460276d48b9ab949c0188d8cfae","function":{"arguments":"{\"location\": \"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"chatcmpl-tool-fd4d9460276d48b9ab949c0188d8cfae","role":"tool"}],"model":"qwen/qwen3-235b-a22b-2507","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n{\"id\":\"gen-1758884946-bwO12CgPbxWTNCrT2DXz\",\"provider\":\"DeepInfra\",\"model\":\"qwen/qwen3-235b-a22b-2507\",\"object\":\"chat.completion\",\"created\":1758884946,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The current temperature in Florence, Italy is 40°C. That's quite hot! Make sure to stay hydrated and avoid prolonged exposure to the sun if you're there.\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":205,\"completion_tokens\":35,\"total_tokens\":240,\"cost\":0.00003945,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00001845,\"upstream_inference_completions_cost\":0.000021},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 778.53375ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/tool_streaming.yaml
new file mode 100644
index 000000000..5a911db58
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommon/qwen3-235b-a22b-2507/tool_streaming.yaml
@@ -0,0 +1,145 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 546
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"qwen/qwen3-235b-a22b-2507","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884947-qO8jdwDATQJKdeZDxRO0","provider":"DeepInfra","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884947,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884947-qO8jdwDATQJKdeZDxRO0","provider":"DeepInfra","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884947,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"call_8536","function":{"arguments":"{\"location\": \"Florence, Italy\"}","name":"weather"},"type":"function"}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1758884947-qO8jdwDATQJKdeZDxRO0","provider":"DeepInfra","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884947,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}]}
+
+ data: {"id":"gen-1758884947-qO8jdwDATQJKdeZDxRO0","provider":"DeepInfra","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884947,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":167,"completion_tokens":21,"total_tokens":188,"cost":0.00002763,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00001503,"upstream_inference_completions_cost":0.0000126},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 719.26375ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 759
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_8536","function":{"arguments":"{\"location\": \"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"call_8536","role":"tool"}],"model":"qwen/qwen3-235b-a22b-2507","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.3.0
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":"The"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" current"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" temperature"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" in"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" Florence"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":","},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" Italy"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" is"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":"4"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":"0"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":"°C"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":"."},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" That"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":"'s"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" quite"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" hot"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":"!"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" Make"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" sure"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" to"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" stay"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" hydrated"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" and"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" protect"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" yourself"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" from"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" the"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" sun"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" if"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" you"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":"'re"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":" outdoors"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":"."},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1758884948-DgNy66DNC6nil5wjSvXn","provider":"Novita","model":"qwen/qwen3-235b-a22b-2507","object":"chat.completion.chunk","created":1758884948,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":205,"completion_tokens":35,"total_tokens":240,"cost":0.00005875,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00003075,"upstream_inference_completions_cost":0.000028},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.275518667s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/multi_tool.yaml
new file mode 100644
index 000000000..2c4a93361
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 929
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system","cache_control":{"type":"ephemeral"}},{"content":"Add and multiply the number 2 and 3","role":"user","cache_control":{"type":"ephemeral"}}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761040270-XYCOhXgdvda3EpjQ9APE\",\"provider\":\"Google\",\"model\":\"anthropic/claude-sonnet-4\",\"object\":\"chat.completion\",\"created\":1761040270,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"I'll add and multiply the numbers 2 and 3 for you.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"id\":\"toolu_vrtx_013K1NSStCjywK6TXC6HRqGP\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"add\",\"arguments\":\"{\\\"a\\\": 2, \\\"b\\\": 3}\"}},{\"id\":\"toolu_vrtx_01873c8uKyyd2q6xVshGqxz3\",\"index\":1,\"type\":\"function\",\"function\":{\"name\":\"multiply\",\"arguments\":\"{\\\"a\\\": 2, \\\"b\\\": 3}\"}}]}}],\"usage\":{\"prompt_tokens\":507,\"completion_tokens\":137,\"total_tokens\":644,\"cost\":0.003576,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.001521,\"upstream_inference_completions_cost\":0.002055},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.091348709s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1447
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system","cache_control":{"type":"ephemeral"}},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"I''ll add and multiply the numbers 2 and 3 for you.","tool_calls":[{"id":"toolu_vrtx_013K1NSStCjywK6TXC6HRqGP","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"toolu_vrtx_01873c8uKyyd2q6xVshGqxz3","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function","cache_control":{"type":"ephemeral"}}],"role":"assistant"},{"content":"5","tool_call_id":"toolu_vrtx_013K1NSStCjywK6TXC6HRqGP","role":"tool"},{"content":"6","tool_call_id":"toolu_vrtx_01873c8uKyyd2q6xVshGqxz3","role":"tool"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n{\"id\":\"gen-1761040274-V2Cp7kWlAUanUV04crBf\",\"provider\":\"Google\",\"model\":\"anthropic/claude-sonnet-4\",\"object\":\"chat.completion\",\"created\":1761040274,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The results are:\\n- Adding 2 and 3: **5**\\n- Multiplying 2 and 3: **6**\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":705,\"completion_tokens\":35,\"total_tokens\":740,\"cost\":0.00264,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.002115,\"upstream_inference_completions_cost\":0.000525},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.372238125s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/multi_tool_streaming.yaml
new file mode 100644
index 000000000..0664623da
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/multi_tool_streaming.yaml
@@ -0,0 +1,133 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 966
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system","cache_control":{"type":"ephemeral"}},{"content":"Add and multiply the number 2 and 3","role":"user","cache_control":{"type":"ephemeral"}}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":"I'll add an","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":"d multiply the numbers 2 and 3 for","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":" you.","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"toolu_vrtx_01AfGThX1SaZp17tWuEGFDQC","index":0,"type":"function","function":{"name":"add","arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"{\"a"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"\":"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":" 2"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":", \"b\": "}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"3}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"toolu_vrtx_01NrRcq2dJXe1HWXoENTKXMD","index":1,"type":"function","function":{"name":"multiply","arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"type":"function","function":{"arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"type":"function","function":{"arguments":"{\"a"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"type":"function","function":{"arguments":"\": "}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"type":"function","function":{"arguments":"2"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"type":"function","function":{"arguments":", \"b\""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":1,"type":"function","function":{"arguments":": 3}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}]}
+
+ data: {"id":"gen-1761040275-09zqoLwdRF08XgqRqNQ4","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040275,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":502,"completion_tokens":137,"total_tokens":639,"cost":0.003561,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.001506,"upstream_inference_completions_cost":0.002055},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.266440542s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1484
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system","cache_control":{"type":"ephemeral"}},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"I''ll add and multiply the numbers 2 and 3 for you.","tool_calls":[{"id":"toolu_vrtx_01AfGThX1SaZp17tWuEGFDQC","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"toolu_vrtx_01NrRcq2dJXe1HWXoENTKXMD","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function","cache_control":{"type":"ephemeral"}}],"role":"assistant"},{"content":"5","tool_call_id":"toolu_vrtx_01AfGThX1SaZp17tWuEGFDQC","role":"tool"},{"content":"6","tool_call_id":"toolu_vrtx_01NrRcq2dJXe1HWXoENTKXMD","role":"tool"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761040278-Sj1JVJx0bzR7Q5Ml7jEP","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040278,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040278-Sj1JVJx0bzR7Q5Ml7jEP","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040278,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040278-Sj1JVJx0bzR7Q5Ml7jEP","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040278,"choices":[{"index":0,"delta":{"role":"assistant","content":"The","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040278-Sj1JVJx0bzR7Q5Ml7jEP","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040278,"choices":[{"index":0,"delta":{"role":"assistant","content":" results are:\n- ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040278-Sj1JVJx0bzR7Q5Ml7jEP","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040278,"choices":[{"index":0,"delta":{"role":"assistant","content":"2 + 3 = ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040278-Sj1JVJx0bzR7Q5Ml7jEP","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040278,"choices":[{"index":0,"delta":{"role":"assistant","content":"5\n- 2 Ć ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040278-Sj1JVJx0bzR7Q5Ml7jEP","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040278,"choices":[{"index":0,"delta":{"role":"assistant","content":"3 = 6","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040278-Sj1JVJx0bzR7Q5Ml7jEP","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040278,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040278-Sj1JVJx0bzR7Q5Ml7jEP","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040278,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1761040278-Sj1JVJx0bzR7Q5Ml7jEP","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040278,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":700,"completion_tokens":31,"total_tokens":731,"cost":0.002565,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0021,"upstream_inference_completions_cost":0.000465},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.925341541s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/simple.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/simple.yaml
new file mode 100644
index 000000000..cb0439670
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 274
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system","cache_control":{"type":"ephemeral"}},{"content":"Say hi in Portuguese","role":"user","cache_control":{"type":"ephemeral"}}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n{\"id\":\"gen-1761040327-k9AqWBidca9ypY5fr23I\",\"provider\":\"Google\",\"model\":\"anthropic/claude-sonnet-4\",\"object\":\"chat.completion\",\"created\":1761040327,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"OlĆ”! \\n\\n(That's \\\"hi\\\" in Portuguese!)\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":16,\"completion_tokens\":18,\"total_tokens\":34,\"cost\":0.000318,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.000048,\"upstream_inference_completions_cost\":0.00027},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.178872834s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/simple_streaming.yaml
new file mode 100644
index 000000000..4ff88c641
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/simple_streaming.yaml
@@ -0,0 +1,54 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 328
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system","cache_control":{"type":"ephemeral"}},{"content":"Say hi in Portuguese","role":"user","cache_control":{"type":"ephemeral"}}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761040328-vqC1YcRuKPi3xRLkXkbc","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040328,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040328-vqC1YcRuKPi3xRLkXkbc","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040328,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040328-vqC1YcRuKPi3xRLkXkbc","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040328,"choices":[{"index":0,"delta":{"role":"assistant","content":"OlĆ”! (","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040328-vqC1YcRuKPi3xRLkXkbc","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040328,"choices":[{"index":0,"delta":{"role":"assistant","content":"Hello!)\n\nYou can also","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040328-vqC1YcRuKPi3xRLkXkbc","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040328,"choices":[{"index":0,"delta":{"role":"assistant","content":" say \"Oi!\"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040328-vqC1YcRuKPi3xRLkXkbc","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040328,"choices":[{"index":0,"delta":{"role":"assistant","content":" which is a more casual way to say hi","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040328-vqC1YcRuKPi3xRLkXkbc","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040328,"choices":[{"index":0,"delta":{"role":"assistant","content":" in Portuguese.","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040328-vqC1YcRuKPi3xRLkXkbc","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040328,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040328-vqC1YcRuKPi3xRLkXkbc","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040328,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1761040328-vqC1YcRuKPi3xRLkXkbc","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040328,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":16,"completion_tokens":32,"total_tokens":48,"cost":0.000528,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.000048,"upstream_inference_completions_cost":0.00048},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.357996709s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/tool.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/tool.yaml
new file mode 100644
index 000000000..53676d62d
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 566
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system","cache_control":{"type":"ephemeral"}},{"content":"What''s the weather in Florence,Italy?","role":"user","cache_control":{"type":"ephemeral"}}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761040259-QBFAtMx2kaNG7X37Hq7X\",\"provider\":\"Google\",\"model\":\"anthropic/claude-sonnet-4\",\"object\":\"chat.completion\",\"created\":1761040259,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"I'll get the weather information for Florence, Italy for you.\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"id\":\"toolu_vrtx_0158fPgA9JyVjvGhTUZq7dWu\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\": \\\"Florence,Italy\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":394,\"completion_tokens\":67,\"total_tokens\":461,\"cost\":0.002187,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.001182,\"upstream_inference_completions_cost\":0.001005},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.238748292s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 904
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system","cache_control":{"type":"ephemeral"}},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"I''ll get the weather information for Florence, Italy for you.","tool_calls":[{"id":"toolu_vrtx_0158fPgA9JyVjvGhTUZq7dWu","function":{"arguments":"{\"location\": \"Florence,Italy\"}","name":"weather"},"type":"function","cache_control":{"type":"ephemeral"}}],"role":"assistant"},{"content":"40 C","tool_call_id":"toolu_vrtx_0158fPgA9JyVjvGhTUZq7dWu","role":"tool"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761040262-Wk5GFVaAOvO1uHRmauN3\",\"provider\":\"Google\",\"model\":\"anthropic/claude-sonnet-4\",\"object\":\"chat.completion\",\"created\":1761040262,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The current weather in Florence, Italy is 40°C (104°F). That's quite hot! Make sure to stay hydrated and seek shade or air conditioning if you're planning to be outdoors.\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":476,\"completion_tokens\":46,\"total_tokens\":522,\"cost\":0.002118,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.001428,\"upstream_inference_completions_cost\":0.00069},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.167850083s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/tool_streaming.yaml
new file mode 100644
index 000000000..35732824e
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterCommonWithAnthropicCache/claude-sonnet-4/tool_streaming.yaml
@@ -0,0 +1,123 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 620
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system","cache_control":{"type":"ephemeral"}},{"content":"What''s the weather in Florence,Italy?","role":"user","cache_control":{"type":"ephemeral"}}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":"I'll get","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":" the weather information for Florence, Italy for","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":" you.","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"toolu_vrtx_0158fGNhdp5B4wCThp4zjSD8","index":0,"type":"function","function":{"name":"weather","arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"{\""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"location\": "}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"\"Flore"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"nce"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":",Ital"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"y\"}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}]}
+
+ data: {"id":"gen-1761040265-t01bhiOqW2wY3pKo18Xy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040265,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":394,"completion_tokens":67,"total_tokens":461,"cost":0.002187,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.001182,"upstream_inference_completions_cost":0.001005},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 3.163571709s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 958
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system","cache_control":{"type":"ephemeral"}},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"I''ll get the weather information for Florence, Italy for you.","tool_calls":[{"id":"toolu_vrtx_0158fGNhdp5B4wCThp4zjSD8","function":{"arguments":"{\"location\": \"Florence,Italy\"}","name":"weather"},"type":"function","cache_control":{"type":"ephemeral"}}],"role":"assistant"},{"content":"40 C","tool_call_id":"toolu_vrtx_0158fGNhdp5B4wCThp4zjSD8","role":"tool"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761040268-tegmh9zIGsP6DUfTBKIq","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040268,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040268-tegmh9zIGsP6DUfTBKIq","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040268,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040268-tegmh9zIGsP6DUfTBKIq","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040268,"choices":[{"index":0,"delta":{"role":"assistant","content":"The","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040268-tegmh9zIGsP6DUfTBKIq","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040268,"choices":[{"index":0,"delta":{"role":"assistant","content":" current weather in Florence, Italy is ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040268-tegmh9zIGsP6DUfTBKIq","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040268,"choices":[{"index":0,"delta":{"role":"assistant","content":"40°C (104°F).","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040268-tegmh9zIGsP6DUfTBKIq","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040268,"choices":[{"index":0,"delta":{"role":"assistant","content":" That's quite hot! If you're planning to visit or","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040268-tegmh9zIGsP6DUfTBKIq","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040268,"choices":[{"index":0,"delta":{"role":"assistant","content":" are currently there, make sure to","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040268-tegmh9zIGsP6DUfTBKIq","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040268,"choices":[{"index":0,"delta":{"role":"assistant","content":" stay hydrated and seek shade during the hottest parts of the","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040268-tegmh9zIGsP6DUfTBKIq","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040268,"choices":[{"index":0,"delta":{"role":"assistant","content":" day.","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040268-tegmh9zIGsP6DUfTBKIq","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040268,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761040268-tegmh9zIGsP6DUfTBKIq","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040268,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1761040268-tegmh9zIGsP6DUfTBKIq","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761040268,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":476,"completion_tokens":54,"total_tokens":530,"cost":0.002238,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.001428,"upstream_inference_completions_cost":0.00081},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.179744666s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterThinking/claude-sonnet-4-sig/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/claude-sonnet-4-sig/thinking-streaming.yaml
new file mode 100644
index 000000000..dcd93b5a3
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/claude-sonnet-4-sig/thinking-streaming.yaml
@@ -0,0 +1,137 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 561
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"anthropic/claude-sonnet-4","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.text","text":"","signature":"","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"The user is asking for","reasoning_details":[{"type":"reasoning.text","text":"The user is asking for","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather information for Florence, Italy. I have","reasoning_details":[{"type":"reasoning.text","text":" weather information for Florence, Italy. I have","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a weather function available that takes","reasoning_details":[{"type":"reasoning.text","text":" a weather function available that takes","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a location parameter. The","reasoning_details":[{"type":"reasoning.text","text":" a location parameter. The","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user has provided the specific","reasoning_details":[{"type":"reasoning.text","text":" user has provided the specific","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" location \"Florence, Italy\" so","reasoning_details":[{"type":"reasoning.text","text":" location \"Florence, Italy\" so","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I have all the required parameters to","reasoning_details":[{"type":"reasoning.text","text":" I have all the required parameters to","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" make the function call.","reasoning_details":[{"type":"reasoning.text","text":" make the function call.","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.text","signature":"Eq0DCkYICBgCKkB2atvgnItYT73m/bhUANGG8tjfCxul+vY0g7SfNEDAgYkioHTPk+qo1xcapnLTuDzEd3CicghnBnSeQ/dBWVXoEgya5GX2XIC3kOKrG5caDIB9MmzFQK/34UUHfiIwllwF4InQp/zhfb+OgFuf9jKbh1SpsBK2K6PV8PB7cfb4+7k9qCM7yL7nmc2YGxsQKpQCTOA18tFgAY4dQX0FxgBJsWlVYEe3/TzSuM3jHkFuOF8u8Wgmjw5imqfKpF9ibWOjHPA6LjfD1CbsQKKv/0C7AzPyJsQ+p11pGZiSL1aASSMYCYjTLdi2Vv35wTQc7a0UngSHKtQ6ZahVvkd5y3JoZ7FMsdOtJQNCBu7ReJ+aicL4aVsZE0hrGIIDcKYyey/oyVjDyyfbQ3BwXdwTsb2i6BnW1KpzVSQSbqP3283WZUAKxygTWLas/DSHrHmZ6Bg2HiPcet/ZIdNnABVVJd90GLiZ6VpWKuLvYk9JYdUlYrhxbhwCcWGqRcL40TgtLAW3tjlLWXKHkVKmv35z8gJ1r6MAYGlpCToRfVvf5Ni2vrk/r5LYGAE=","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"toolu_01J2NHBpWgZG12484BtrxsNF","index":0,"type":"function","function":{"name":"weather","arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"{\"locatio"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"n\": \"Flor"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"enc"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"e,"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":" Italy\"}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}]}
+
+ data: {"id":"gen-1761052928-cSHiiIJW2besxl4lmO80","provider":"Anthropic","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052928,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":423,"completion_tokens":111,"total_tokens":534,"cost":0.002934,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.001269,"upstream_inference_completions_cost":0.001665},"completion_tokens_details":{"reasoning_tokens":65,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.876808709s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2047
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"toolu_01J2NHBpWgZG12484BtrxsNF","function":{"arguments":"{\"location\": \"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"anthropic-claude-v1","index":0,"signature":"Eq0DCkYICBgCKkB2atvgnItYT73m/bhUANGG8tjfCxul+vY0g7SfNEDAgYkioHTPk+qo1xcapnLTuDzEd3CicghnBnSeQ/dBWVXoEgya5GX2XIC3kOKrG5caDIB9MmzFQK/34UUHfiIwllwF4InQp/zhfb+OgFuf9jKbh1SpsBK2K6PV8PB7cfb4+7k9qCM7yL7nmc2YGxsQKpQCTOA18tFgAY4dQX0FxgBJsWlVYEe3/TzSuM3jHkFuOF8u8Wgmjw5imqfKpF9ibWOjHPA6LjfD1CbsQKKv/0C7AzPyJsQ+p11pGZiSL1aASSMYCYjTLdi2Vv35wTQc7a0UngSHKtQ6ZahVvkd5y3JoZ7FMsdOtJQNCBu7ReJ+aicL4aVsZE0hrGIIDcKYyey/oyVjDyyfbQ3BwXdwTsb2i6BnW1KpzVSQSbqP3283WZUAKxygTWLas/DSHrHmZ6Bg2HiPcet/ZIdNnABVVJd90GLiZ6VpWKuLvYk9JYdUlYrhxbhwCcWGqRcL40TgtLAW3tjlLWXKHkVKmv35z8gJ1r6MAYGlpCToRfVvf5Ni2vrk/r5LYGAE=","text":"The user is asking for weather information for Florence, Italy. I have a weather function available that takes a location parameter. The user has provided the specific location \"Florence, Italy\" so I have all the required parameters to make the function call.","type":"reasoning.text"}],"reasoning":"The user is asking for weather information for Florence, Italy. I have a weather function available that takes a location parameter. The user has provided the specific location \"Florence, Italy\" so I have all the required parameters to make the function call."},{"content":"40 C","tool_call_id":"toolu_01J2NHBpWgZG12484BtrxsNF","role":"tool"}],"model":"anthropic/claude-sonnet-4","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761052931-bQBfkvYvunOtBexaDWxh","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052931,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052931-bQBfkvYvunOtBexaDWxh","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052931,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052931-bQBfkvYvunOtBexaDWxh","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052931,"choices":[{"index":0,"delta":{"role":"assistant","content":"The","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052931-bQBfkvYvunOtBexaDWxh","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052931,"choices":[{"index":0,"delta":{"role":"assistant","content":" current","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052931-bQBfkvYvunOtBexaDWxh","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052931,"choices":[{"index":0,"delta":{"role":"assistant","content":" weather in Florence, Italy is 40","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052931-bQBfkvYvunOtBexaDWxh","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052931,"choices":[{"index":0,"delta":{"role":"assistant","content":"°C (104°F). That","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052931-bQBfkvYvunOtBexaDWxh","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052931,"choices":[{"index":0,"delta":{"role":"assistant","content":"'s quite","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052931-bQBfkvYvunOtBexaDWxh","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052931,"choices":[{"index":0,"delta":{"role":"assistant","content":" hot","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052931-bQBfkvYvunOtBexaDWxh","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052931,"choices":[{"index":0,"delta":{"role":"assistant","content":"! It's a very","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052931-bQBfkvYvunOtBexaDWxh","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052931,"choices":[{"index":0,"delta":{"role":"assistant","content":" warm day there","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052931-bQBfkvYvunOtBexaDWxh","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052931,"choices":[{"index":0,"delta":{"role":"assistant","content":".","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052931-bQBfkvYvunOtBexaDWxh","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052931,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052931-bQBfkvYvunOtBexaDWxh","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052931,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1761052931-bQBfkvYvunOtBexaDWxh","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052931,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":549,"completion_tokens":33,"total_tokens":582,"cost":0.002142,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.001647,"upstream_inference_completions_cost":0.000495},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.208550625s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterThinking/claude-sonnet-4-sig/thinking.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/claude-sonnet-4-sig/thinking.yaml
new file mode 100644
index 000000000..0e8df092e
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/claude-sonnet-4-sig/thinking.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 507
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"anthropic/claude-sonnet-4","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"reasoning":{"effort":"medium"}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761052922-O8XtvXkfi2FIFvCpk15W\",\"provider\":\"Anthropic\",\"model\":\"anthropic/claude-sonnet-4\",\"object\":\"chat.completion\",\"created\":1761052922,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":\"The user is asking for weather information for Florence, Italy. I have access to a weather function that takes a location parameter. The user has provided a specific location: \\\"Florence, Italy\\\". I have all the required parameters to make this function call.\",\"tool_calls\":[{\"id\":\"toolu_01G9Rea1VaAehQhQTRxGbVt3\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\": \\\"Florence, Italy\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"The user is asking for weather information for Florence, Italy. I have access to a weather function that takes a location parameter. The user has provided a specific location: \\\"Florence, Italy\\\". I have all the required parameters to make this function call.\",\"signature\":\"EqsDCkYICBgCKkBZgA2aLmZQDmRH4RVCT4iXR95b6oYoMjp4e2kPdf2Po5wKmOD2b4fyCcDgesqaf1am+tK5ghnLAfrPp0kAa4ZmEgyC28uLu7gtwja44EwaDGEcw3jGVOOMdTIw8yIwSMENWo4hxw+0D7N8nGHs7R8ff6mL6SamfS9mM31bjlsXl3yqJUnue4qM/5T1eypWKpICoSCTYqxL31KjmP/dpTTAq92sGpdAH/qnrihAGrygZOmaCiKGvnd0+ZSOkFl5YLew53NbGFndgDOIAVZw/MwBm/Q/FfaRCKe3ha3jDSb7kKcMrYYiYeYaQ0em0z83TQBexlomR/8PRTmj6+P52DqmRRqFn32uOurrPFMcQ+/m8W8GR7BtS2zg8gnX0f2ZBZe021KsN2mNGipfeVUtW7ByM69HTYltfMGqsB/voa6VQRxMA7MWPhQTedIs4twaSxmoBUjZh5MQUhgeQX8GUOJtVBi8UL/l3uOjf21bHpVsi/3kEaWDtCu40aRsuvs5LxQ8oPr28gty6p/5CUWuoo2rfEPD6N6FbdBya1XNUzSAJPulQRgB\",\"format\":\"anthropic-claude-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":423,\"completion_tokens\":112,\"total_tokens\":535,\"cost\":0.002949,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.001269,\"upstream_inference_completions_cost\":0.00168},\"completion_tokens_details\":{\"reasoning_tokens\":65,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.264924084s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1985
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"toolu_01G9Rea1VaAehQhQTRxGbVt3","function":{"arguments":"{\"location\": \"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"anthropic-claude-v1","index":0,"signature":"EqsDCkYICBgCKkBZgA2aLmZQDmRH4RVCT4iXR95b6oYoMjp4e2kPdf2Po5wKmOD2b4fyCcDgesqaf1am+tK5ghnLAfrPp0kAa4ZmEgyC28uLu7gtwja44EwaDGEcw3jGVOOMdTIw8yIwSMENWo4hxw+0D7N8nGHs7R8ff6mL6SamfS9mM31bjlsXl3yqJUnue4qM/5T1eypWKpICoSCTYqxL31KjmP/dpTTAq92sGpdAH/qnrihAGrygZOmaCiKGvnd0+ZSOkFl5YLew53NbGFndgDOIAVZw/MwBm/Q/FfaRCKe3ha3jDSb7kKcMrYYiYeYaQ0em0z83TQBexlomR/8PRTmj6+P52DqmRRqFn32uOurrPFMcQ+/m8W8GR7BtS2zg8gnX0f2ZBZe021KsN2mNGipfeVUtW7ByM69HTYltfMGqsB/voa6VQRxMA7MWPhQTedIs4twaSxmoBUjZh5MQUhgeQX8GUOJtVBi8UL/l3uOjf21bHpVsi/3kEaWDtCu40aRsuvs5LxQ8oPr28gty6p/5CUWuoo2rfEPD6N6FbdBya1XNUzSAJPulQRgB","text":"The user is asking for weather information for Florence, Italy. I have access to a weather function that takes a location parameter. The user has provided a specific location: \"Florence, Italy\". I have all the required parameters to make this function call.","type":"reasoning.text"}],"reasoning":"The user is asking for weather information for Florence, Italy. I have access to a weather function that takes a location parameter. The user has provided a specific location: \"Florence, Italy\". I have all the required parameters to make this function call."},{"content":"40 C","tool_call_id":"toolu_01G9Rea1VaAehQhQTRxGbVt3","role":"tool"}],"model":"anthropic/claude-sonnet-4","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761052925-AxTrfKwZfWd4u7iT2kxf\",\"provider\":\"Anthropic\",\"model\":\"anthropic/claude-sonnet-4\",\"object\":\"chat.completion\",\"created\":1761052925,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The current temperature in Florence, Italy is 40°C (104°F). That's quite hot! It's a very warm day in Florence.\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":550,\"completion_tokens\":34,\"total_tokens\":584,\"cost\":0.00216,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00165,\"upstream_inference_completions_cost\":0.00051},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.506909292s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterThinking/claude-sonnet-4/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/claude-sonnet-4/thinking-streaming.yaml
new file mode 100644
index 000000000..4670eddf1
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/claude-sonnet-4/thinking-streaming.yaml
@@ -0,0 +1,155 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 561
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"anthropic/claude-sonnet-4","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"reasoning":{"effort":"medium"},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.text","text":"","signature":"","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"The user is asking for","reasoning_details":[{"type":"reasoning.text","text":"The user is asking for","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.text","text":" weather","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" information for Florence, Italy. I have","reasoning_details":[{"type":"reasoning.text","text":" information for Florence, Italy. I have","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" access","reasoning_details":[{"type":"reasoning.text","text":" access","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to a","reasoning_details":[{"type":"reasoning.text","text":" to a","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.text","text":" weather","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" function","reasoning_details":[{"type":"reasoning.text","text":" function","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" that takes","reasoning_details":[{"type":"reasoning.text","text":" that takes","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a location parameter. The","reasoning_details":[{"type":"reasoning.text","text":" a location parameter. The","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.text","text":" user","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" has","reasoning_details":[{"type":"reasoning.text","text":" has","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" provided the location as \"Florence, Italy","reasoning_details":[{"type":"reasoning.text","text":" provided the location as \"Florence, Italy","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\". I have","reasoning_details":[{"type":"reasoning.text","text":"\". I have","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" all the required parameters to make this function","reasoning_details":[{"type":"reasoning.text","text":" all the required parameters to make this function","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" call.","reasoning_details":[{"type":"reasoning.text","text":" call.","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.text","signature":"EqgDCkgICBACGAIqQBvYK+UwzOLw+Jn8uxD4xoXAM70ym9hFuly64akWaZWJmCZFKC5FUckRcFdakI9/WwJTg2/OdypSRSFtMKW4iDYSDLfy1OwcX/ce7UF27BoMZSMVXAzI69NJbbpRIjAHt993gWGqLdpBx4VZpiE/KzXGuWCtwOhGqtZpDSoieeHCkybItGtT6z6iICSyEZcqjQLvPSxhozPhmWnYCYD9l276wOYIe4Ij/VDzNH/BO+/FQpmM9Z6WvveF5Gwii8lypjywLedePdHZIKhytZDhEDZsaPYbW8WKupYjh6//EfU1Lrf8A8qXs0A3vZxOWAD2y1BqTM6q2PZ1Qbi/W6rPsT6Xc3IQhArlRC402b5cJhrBADH10ZTntkgh7NeIbCl6mQ9qLN2WUltLmhP2zhzJ7eAEJRc5wk3gK3usZ5wfo5U6ZNoCxBOTUYkjYmasuOZGVugU6pBcEZiawvhThKuCuQ5tAR1Ac7n/5b0+lPZS6iYTyhrLL9ftNAAAhQfpmpjohh232Ub59UO7UnH7ydxDK3xLloVprJMwTwatMEl9uxgB","format":"anthropic-claude-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"toolu_vrtx_015KCHmsJaGhVoVK8owtCkHi","index":0,"type":"function","function":{"name":"weather","arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"{\"locat"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"ion\": \"Flore"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"nce, Italy\"}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}]}
+
+ data: {"id":"gen-1761052874-j8EWFeK5gEAxzynOutxy","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052874,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":423,"completion_tokens":111,"total_tokens":534,"cost":0.002934,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.001269,"upstream_inference_completions_cost":0.001665},"completion_tokens_details":{"reasoning_tokens":63,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.593338833s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2035
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"toolu_vrtx_015KCHmsJaGhVoVK8owtCkHi","function":{"arguments":"{\"location\": \"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning":"The user is asking for weather information for Florence, Italy. I have access to a weather function that takes a location parameter. The user has provided the location as \"Florence, Italy\". I have all the required parameters to make this function call.","reasoning_details":[{"format":"anthropic-claude-v1","index":0,"signature":"EqgDCkgICBACGAIqQBvYK+UwzOLw+Jn8uxD4xoXAM70ym9hFuly64akWaZWJmCZFKC5FUckRcFdakI9/WwJTg2/OdypSRSFtMKW4iDYSDLfy1OwcX/ce7UF27BoMZSMVXAzI69NJbbpRIjAHt993gWGqLdpBx4VZpiE/KzXGuWCtwOhGqtZpDSoieeHCkybItGtT6z6iICSyEZcqjQLvPSxhozPhmWnYCYD9l276wOYIe4Ij/VDzNH/BO+/FQpmM9Z6WvveF5Gwii8lypjywLedePdHZIKhytZDhEDZsaPYbW8WKupYjh6//EfU1Lrf8A8qXs0A3vZxOWAD2y1BqTM6q2PZ1Qbi/W6rPsT6Xc3IQhArlRC402b5cJhrBADH10ZTntkgh7NeIbCl6mQ9qLN2WUltLmhP2zhzJ7eAEJRc5wk3gK3usZ5wfo5U6ZNoCxBOTUYkjYmasuOZGVugU6pBcEZiawvhThKuCuQ5tAR1Ac7n/5b0+lPZS6iYTyhrLL9ftNAAAhQfpmpjohh232Ub59UO7UnH7ydxDK3xLloVprJMwTwatMEl9uxgB","text":"The user is asking for weather information for Florence, Italy. I have access to a weather function that takes a location parameter. The user has provided the location as \"Florence, Italy\". I have all the required parameters to make this function call.","type":"reasoning.text"}]},{"content":"40 C","tool_call_id":"toolu_vrtx_015KCHmsJaGhVoVK8owtCkHi","role":"tool"}],"model":"anthropic/claude-sonnet-4","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":"The","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":" current","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":" weather in Florence, Italy is ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":"40°C (104°F).","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":" That","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":"'s quite","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":" hot","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":"! Make","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":" sure to stay hydrated and seek","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":" shade if","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":" you're planning","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":" to be out","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":"doors.","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}]}
+
+ data: {"id":"gen-1761052876-A1tgi5ujdynpoIs5bgIZ","provider":"Google","model":"anthropic/claude-sonnet-4","object":"chat.completion.chunk","created":1761052876,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":549,"completion_tokens":43,"total_tokens":592,"cost":0.002292,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.001647,"upstream_inference_completions_cost":0.000645},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.177272083s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterThinking/claude-sonnet-4/thinking.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/claude-sonnet-4/thinking.yaml
new file mode 100644
index 000000000..3b32235a3
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/claude-sonnet-4/thinking.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 507
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"anthropic/claude-sonnet-4","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761052869-MiFiSdXtA37nGboSrMvb\",\"provider\":\"Google\",\"model\":\"anthropic/claude-sonnet-4\",\"object\":\"chat.completion\",\"created\":1761052869,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":\"The user is asking for weather information for Florence, Italy. I have access to a weather function that takes a location parameter. The user has provided the location as \\\"Florence, Italy\\\". I have all the required parameters to make the function call.\",\"tool_calls\":[{\"id\":\"toolu_vrtx_011RyUyxRuzVNFcHaBZvofi5\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\": \\\"Florence, Italy\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"The user is asking for weather information for Florence, Italy. I have access to a weather function that takes a location parameter. The user has provided the location as \\\"Florence, Italy\\\". I have all the required parameters to make the function call.\",\"signature\":\"EqcDCkgICBACGAIqQGxS3uOazXwdlJW9xlFvmyUOv4JjTZPQp7+x6B2nS+pe1Md3qoC16keCnhgLxEg3iNLgDcQCRlslDavs7Kw3ubUSDFCi9WxMGdOC0gZUhBoMDq0EUJo3Ve5VsKtqIjBwlSUZTmw8m53eg0M4kDsNM/26mgn0UFYPXUniuSn1SKHY4MD287XzAW03ze71+9UqjAKLjp8TcKqXLCwwK/duwkLX2APzoovXso0B4cCLL4S4rwVMQd4yXgMyuktRLbgewgOYdJYu9RJuXrYgWEnEtzgyWpUlEPA3jje5nrsxEWFwduBEWt5eZXM0nbChoCjusYEgSOb/FalXPKd6m05u+R2KZC+If8Ry13Yf01EGylhiUBHFZe4Xr3O8F8kSgzUMIrdZZZ42DbCfgP3qXBTapbis098WRF8f+jWfGZCu4UuK9KL+c3kcSGXv3qlGkGRFC0+f5vhikSmoVst1rZ9JUErmZd61EYVD3A5oSz1p4sKODjV1emp+Vh1EQWnDOJG2ccASGQpfpOFcYbUPuAaSNWDCeqpWfpZ12rHywqV7GAE=\",\"format\":\"anthropic-claude-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":423,\"completion_tokens\":111,\"total_tokens\":534,\"cost\":0.002934,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.001269,\"upstream_inference_completions_cost\":0.001665},\"completion_tokens_details\":{\"reasoning_tokens\":63,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.574778833s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1979
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"toolu_vrtx_011RyUyxRuzVNFcHaBZvofi5","function":{"arguments":"{\"location\": \"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"anthropic-claude-v1","index":0,"signature":"EqcDCkgICBACGAIqQGxS3uOazXwdlJW9xlFvmyUOv4JjTZPQp7+x6B2nS+pe1Md3qoC16keCnhgLxEg3iNLgDcQCRlslDavs7Kw3ubUSDFCi9WxMGdOC0gZUhBoMDq0EUJo3Ve5VsKtqIjBwlSUZTmw8m53eg0M4kDsNM/26mgn0UFYPXUniuSn1SKHY4MD287XzAW03ze71+9UqjAKLjp8TcKqXLCwwK/duwkLX2APzoovXso0B4cCLL4S4rwVMQd4yXgMyuktRLbgewgOYdJYu9RJuXrYgWEnEtzgyWpUlEPA3jje5nrsxEWFwduBEWt5eZXM0nbChoCjusYEgSOb/FalXPKd6m05u+R2KZC+If8Ry13Yf01EGylhiUBHFZe4Xr3O8F8kSgzUMIrdZZZ42DbCfgP3qXBTapbis098WRF8f+jWfGZCu4UuK9KL+c3kcSGXv3qlGkGRFC0+f5vhikSmoVst1rZ9JUErmZd61EYVD3A5oSz1p4sKODjV1emp+Vh1EQWnDOJG2ccASGQpfpOFcYbUPuAaSNWDCeqpWfpZ12rHywqV7GAE=","text":"The user is asking for weather information for Florence, Italy. I have access to a weather function that takes a location parameter. The user has provided the location as \"Florence, Italy\". I have all the required parameters to make the function call.","type":"reasoning.text"}],"reasoning":"The user is asking for weather information for Florence, Italy. I have access to a weather function that takes a location parameter. The user has provided the location as \"Florence, Italy\". I have all the required parameters to make the function call."},{"content":"40 C","tool_call_id":"toolu_vrtx_011RyUyxRuzVNFcHaBZvofi5","role":"tool"}],"model":"anthropic/claude-sonnet-4","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n{\"id\":\"gen-1761052871-4K3N85WPWxkYpvKAIK7r\",\"provider\":\"Google\",\"model\":\"anthropic/claude-sonnet-4\",\"object\":\"chat.completion\",\"created\":1761052871,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The current weather in Florence, Italy shows a temperature of 40°C (104°F). That's quite hot! It's a very warm day in Florence today.\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":549,\"completion_tokens\":38,\"total_tokens\":587,\"cost\":0.002217,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.001647,\"upstream_inference_completions_cost\":0.00057},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.367055209s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterThinking/gemini-3-pro-preview/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/gemini-3-pro-preview/thinking-streaming.yaml
new file mode 100644
index 000000000..25ff2c903
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/gemini-3-pro-preview/thinking-streaming.yaml
@@ -0,0 +1,77 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 563
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"google/gemini-3-pro-preview","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1763546643-6iyR5xZk4FUZDszB0am5","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546643,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"**Processing Weather Request**\n\nI've zeroed in on the user's weather query and pinpointed the location as Florence, Italy. The next step involves invoking the `get_weather` function, feeding it the identified location as a parameter. It's a straightforward process, I am ready to move on.\n\n\n","reasoning_details":[{"type":"reasoning.text","text":"**Processing Weather Request**\n\nI've zeroed in on the user's weather query and pinpointed the location as Florence, Italy. The next step involves invoking the `get_weather` function, feeding it the identified location as a parameter. It's a straightforward process, I am ready to move on.\n\n\n","format":"google-gemini-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1763546643-6iyR5xZk4FUZDszB0am5","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546643,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"reasoning":null,"reasoning_details":[{"id":"tool_weather_DTRiEM9ZhsGia4wKxtzr","type":"reasoning.encrypted","data":"CiQB4/H/XtQf/t2ivBCPsAJ1IAjit6zgeJbobI/H5w09u43xVM8KZwHj8f9e51jeSFgDf45Pkwo86CrPlD3o8ZyFEE/tLx74kTzrLixqIoG3WAJV4vzbIAAvRRm8HgovZkKLa/qR7XL3QyYKnFSDVbik86ElPf/9E9EbBc18RcBhU30VLLx+QWaL/9w9u/UKaAHj8f9eNB+grvQVrGDcL0BgnNLzSM4mVEAvaPOa6XddLxIi3izFHNpGVtVI1J8ABVPEzAwmZqGcr/NJTJDM+z0pZrnhUEdR5nCMw3/Kk6KH0SoOC+E0E9O8+0uTEZ2aVAIAqdI/cK98CqEBAePx/16FP6yD1/O5En03//g+Ux5rgUEtTKNmAvmlwyFy/62/L4iaDa7V/qSXsh5cjvcuzPGDfNu/E4LF+RrTK23Obdj9sa/CpVR8C//SfsztgPNrnn3DRxf78QYwIVHZeJdWTLsQ7gR97YqqV+p+ljwBkriVJ0hOdxlJzoKSDOqXk5HVLpS95XTVPrclF+TmDww+0YbNFAtIU5jOI465caQ=","format":"google-gemini-v1","index":0}],"tool_calls":[{"index":0,"id":"tool_weather_DTRiEM9ZhsGia4wKxtzr","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence, Italy\"}"}}]},"finish_reason":"tool_calls","native_finish_reason":"STOP","logprobs":null}]}
+
+ data: {"id":"gen-1763546643-6iyR5xZk4FUZDszB0am5","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546643,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":28,"completion_tokens":73,"total_tokens":101,"cost":0.000932,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.000056,"upstream_inference_completions_cost":0.000876},"completion_tokens_details":{"reasoning_tokens":64,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 4.566491625s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1887
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"tool_weather_DTRiEM9ZhsGia4wKxtzr","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"google-gemini-v1","index":0,"text":"**Processing Weather Request**\n\nI''ve zeroed in on the user''s weather query and pinpointed the location as Florence, Italy. The next step involves invoking the `get_weather` function, feeding it the identified location as a parameter. It''s a straightforward process, I am ready to move on.\n\n\n","type":"reasoning.text"},{"data":"CiQB4/H/XtQf/t2ivBCPsAJ1IAjit6zgeJbobI/H5w09u43xVM8KZwHj8f9e51jeSFgDf45Pkwo86CrPlD3o8ZyFEE/tLx74kTzrLixqIoG3WAJV4vzbIAAvRRm8HgovZkKLa/qR7XL3QyYKnFSDVbik86ElPf/9E9EbBc18RcBhU30VLLx+QWaL/9w9u/UKaAHj8f9eNB+grvQVrGDcL0BgnNLzSM4mVEAvaPOa6XddLxIi3izFHNpGVtVI1J8ABVPEzAwmZqGcr/NJTJDM+z0pZrnhUEdR5nCMw3/Kk6KH0SoOC+E0E9O8+0uTEZ2aVAIAqdI/cK98CqEBAePx/16FP6yD1/O5En03//g+Ux5rgUEtTKNmAvmlwyFy/62/L4iaDa7V/qSXsh5cjvcuzPGDfNu/E4LF+RrTK23Obdj9sa/CpVR8C//SfsztgPNrnn3DRxf78QYwIVHZeJdWTLsQ7gR97YqqV+p+ljwBkriVJ0hOdxlJzoKSDOqXk5HVLpS95XTVPrclF+TmDww+0YbNFAtIU5jOI465caQ=","format":"google-gemini-v1","id":"tool_weather_DTRiEM9ZhsGia4wKxtzr","index":0,"type":"reasoning.encrypted"}]},{"content":"40 C","tool_call_id":"tool_weather_DTRiEM9ZhsGia4wKxtzr","role":"tool"}],"model":"google/gemini-3-pro-preview","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1763546647-Tp9ZHwQ3rhhPj6NAdVFO","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546647,"choices":[{"index":0,"delta":{"role":"assistant","content":"The weather","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1763546647-Tp9ZHwQ3rhhPj6NAdVFO","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546647,"choices":[{"index":0,"delta":{"role":"assistant","content":" in Florence, Italy is currently 40°C.","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"STOP","logprobs":null}]}
+
+ data: {"id":"gen-1763546647-Tp9ZHwQ3rhhPj6NAdVFO","provider":"Google","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763546647,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":54,"completion_tokens":14,"total_tokens":68,"cost":0.000276,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.000108,"upstream_inference_completions_cost":0.000168},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.671475084s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterThinking/gemini-3-pro-preview/thinking.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/gemini-3-pro-preview/thinking.yaml
new file mode 100644
index 000000000..84ee5e5e7
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/gemini-3-pro-preview/thinking.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 509
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"google/gemini-3-pro-preview","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1763546487-yFEwYukW5QfhvzEHSekZ\",\"provider\":\"Google AI Studio\",\"model\":\"google/gemini-3-pro-preview\",\"object\":\"chat.completion\",\"created\":1763546488,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":\"**Acquiring Weather Data**\\n\\nI've decided to use the weather tool to get the current forecast for Florence, Italy. The location will be specified as \\\"Florence, Italy\\\" to get the most accurate results. I'm ready to proceed with using the tool and return the information.\\n\\n\\n\",\"tool_calls\":[{\"index\":0,\"id\":\"tool_weather_lYXVFov6DFhVAnGHGzui\",\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"**Acquiring Weather Data**\\n\\nI've decided to use the weather tool to get the current forecast for Florence, Italy. The location will be specified as \\\"Florence, Italy\\\" to get the most accurate results. I'm ready to proceed with using the tool and return the information.\\n\\n\\n\",\"format\":\"google-gemini-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"Eo4CCosCAdHtim9UBFExPDgDuh8MWbVEkO9w+s9pDzoFBZjc7fdzo6eGpv04hlhBygkMpO6VBAIRKEooegdRQnhJUUWJD/Zrf5cfiahXRK4fWPQvTaBxS7+h1HpDORflVhuy2kDFSGDQkI43qaqvIPdBZLuo6P+KEO7rXnRAUJZ5EBhTqszy6qSDBkBZJofLvV0Hrm2AatVECeqV8ZX1fuVZ0vKgzHcE3ZQJD2CX2Hcu1DHf2zZRL9ghxK12GtxwBQjfHVj0uHafLMvMEMyOA6kRDkWRh7q+EPJ1MjCRKsEbZCEh29oXIUZUT9UI96H8harvQ+88L6WuN8AGv9+CFrHuenGzd7SymIM/C4L+vhge\",\"id\":\"tool_weather_lYXVFov6DFhVAnGHGzui\",\"format\":\"google-gemini-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":65,\"completion_tokens\":58,\"total_tokens\":123,\"cost\":0.000826,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00013,\"upstream_inference_completions_cost\":0.000696},\"completion_tokens_details\":{\"reasoning_tokens\":42,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.118976208s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1627
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"tool_weather_lYXVFov6DFhVAnGHGzui","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"google-gemini-v1","index":0,"text":"**Acquiring Weather Data**\n\nI''ve decided to use the weather tool to get the current forecast for Florence, Italy. The location will be specified as \"Florence, Italy\" to get the most accurate results. I''m ready to proceed with using the tool and return the information.\n\n\n","type":"reasoning.text"},{"data":"Eo4CCosCAdHtim9UBFExPDgDuh8MWbVEkO9w+s9pDzoFBZjc7fdzo6eGpv04hlhBygkMpO6VBAIRKEooegdRQnhJUUWJD/Zrf5cfiahXRK4fWPQvTaBxS7+h1HpDORflVhuy2kDFSGDQkI43qaqvIPdBZLuo6P+KEO7rXnRAUJZ5EBhTqszy6qSDBkBZJofLvV0Hrm2AatVECeqV8ZX1fuVZ0vKgzHcE3ZQJD2CX2Hcu1DHf2zZRL9ghxK12GtxwBQjfHVj0uHafLMvMEMyOA6kRDkWRh7q+EPJ1MjCRKsEbZCEh29oXIUZUT9UI96H8harvQ+88L6WuN8AGv9+CFrHuenGzd7SymIM/C4L+vhge","format":"google-gemini-v1","id":"tool_weather_lYXVFov6DFhVAnGHGzui","index":0,"type":"reasoning.encrypted"}]},{"content":"40 C","tool_call_id":"tool_weather_lYXVFov6DFhVAnGHGzui","role":"tool"}],"model":"google/gemini-3-pro-preview","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n{\"id\":\"gen-1763546490-1xpxTRabcgvGkdsoaObe\",\"provider\":\"Google\",\"model\":\"google/gemini-3-pro-preview\",\"object\":\"chat.completion\",\"created\":1763546490,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The weather in Florence is currently 40°C.\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":54,\"completion_tokens\":12,\"total_tokens\":66,\"cost\":0.000252,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.000108,\"upstream_inference_completions_cost\":0.000144},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.710336083s
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterThinking/glm-4.6/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/glm-4.6/thinking-streaming.yaml
new file mode 100644
index 000000000..008725f4b
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/glm-4.6/thinking-streaming.yaml
@@ -0,0 +1,361 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 548
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"z-ai/glm-4.6","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"The","reasoning_details":[{"type":"reasoning.text","text":"The","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.text","text":" user","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" is","reasoning_details":[{"type":"reasoning.text","text":" is","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" asking","reasoning_details":[{"type":"reasoning.text","text":" asking","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.text","text":" for","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.text","text":" weather","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" information","reasoning_details":[{"type":"reasoning.text","text":" information","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.text","text":" for","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.text","text":" Florence","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.text","text":",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Italy","reasoning_details":[{"type":"reasoning.text","text":" Italy","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.text","text":" I","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" have","reasoning_details":[{"type":"reasoning.text","text":" have","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" access","reasoning_details":[{"type":"reasoning.text","text":" access","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.text","text":" to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.text","text":" a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.text","text":" weather","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" function","reasoning_details":[{"type":"reasoning.text","text":" function","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" that","reasoning_details":[{"type":"reasoning.text","text":" that","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" takes","reasoning_details":[{"type":"reasoning.text","text":" takes","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.text","text":" a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" location","reasoning_details":[{"type":"reasoning.text","text":" location","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" parameter","reasoning_details":[{"type":"reasoning.text","text":" parameter","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" The","reasoning_details":[{"type":"reasoning.text","text":" The","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.text","text":" user","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" has","reasoning_details":[{"type":"reasoning.text","text":" has","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" provided","reasoning_details":[{"type":"reasoning.text","text":" provided","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.text","text":" \"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Flo","reasoning_details":[{"type":"reasoning.text","text":"Flo","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"rence","reasoning_details":[{"type":"reasoning.text","text":"rence","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.text","text":",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Italy","reasoning_details":[{"type":"reasoning.text","text":" Italy","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\"","reasoning_details":[{"type":"reasoning.text","text":"\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" as","reasoning_details":[{"type":"reasoning.text","text":" as","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" location.","reasoning_details":[{"type":"reasoning.text","text":" location.","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I should","reasoning_details":[{"type":"reasoning.text","text":" I should","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" use","reasoning_details":[{"type":"reasoning.text","text":" use","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" this","reasoning_details":[{"type":"reasoning.text","text":" this","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" exactly","reasoning_details":[{"type":"reasoning.text","text":" exactly","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" as","reasoning_details":[{"type":"reasoning.text","text":" as","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" provided","reasoning_details":[{"type":"reasoning.text","text":" provided","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" since","reasoning_details":[{"type":"reasoning.text","text":" since","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" it","reasoning_details":[{"type":"reasoning.text","text":" it","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"'s","reasoning_details":[{"type":"reasoning.text","text":"'s","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.text","text":" a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" specific","reasoning_details":[{"type":"reasoning.text","text":" specific","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" location","reasoning_details":[{"type":"reasoning.text","text":" location","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"I","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"'ll","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":" check","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":" the","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":" weather","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":" in","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":" Florence","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":",","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":" Italy","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":" for","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":" you","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":".\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"call_410428ba131746b6ae7ff4bb","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence, Italy\"}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"tool_calls","native_finish_reason":"tool_calls","logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052915-2CCJv3whdOgelTcOt7hS","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052915,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":179,"completion_tokens":85,"total_tokens":264,"cost":0.00020718,"is_byok":false,"prompt_tokens_details":{"cached_tokens":178,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00002018,"upstream_inference_completions_cost":0.000187},"completion_tokens_details":{"reasoning_tokens":65,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.059172958s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1214
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"content":"\n\nI''ll check the weather in Florence, Italy for you.\n","tool_calls":[{"id":"call_410428ba131746b6ae7ff4bb","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"unknown","index":0,"text":" user is asking for weather information for Florence, Italy. I have access to a weather function that takes a location parameter. The user has provided \"Florence, Italy\" as the location. I should use this exactly as provided since it''s a specific location.","type":"reasoning.text"}]},{"content":"40 C","tool_call_id":"call_410428ba131746b6ae7ff4bb","role":"tool"}],"model":"z-ai/glm-4.6","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"The","reasoning_details":[{"type":"reasoning.text","text":"The","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.text","text":" weather","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" function","reasoning_details":[{"type":"reasoning.text","text":" function","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" returned","reasoning_details":[{"type":"reasoning.text","text":" returned","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"40","reasoning_details":[{"type":"reasoning.text","text":" \"40","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" C\"","reasoning_details":[{"type":"reasoning.text","text":" C\"","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.text","text":" for","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.text","text":" Florence","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.text","text":",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Italy","reasoning_details":[{"type":"reasoning.text","text":" Italy","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" This","reasoning_details":[{"type":"reasoning.text","text":" This","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" seems","reasoning_details":[{"type":"reasoning.text","text":" seems","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.text","text":" to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" be","reasoning_details":[{"type":"reasoning.text","text":" be","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.text","text":" a","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" temperature","reasoning_details":[{"type":"reasoning.text","text":" temperature","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" reading","reasoning_details":[{"type":"reasoning.text","text":" reading","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" of","reasoning_details":[{"type":"reasoning.text","text":" of","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ","reasoning_details":[{"type":"reasoning.text","text":" ","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"40","reasoning_details":[{"type":"reasoning.text","text":"40","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" degrees","reasoning_details":[{"type":"reasoning.text","text":" degrees","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Celsius","reasoning_details":[{"type":"reasoning.text","text":" Celsius","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.text","text":",","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" which","reasoning_details":[{"type":"reasoning.text","text":" which","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" is","reasoning_details":[{"type":"reasoning.text","text":" is","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" quite","reasoning_details":[{"type":"reasoning.text","text":" quite","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" hot","reasoning_details":[{"type":"reasoning.text","text":" hot","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.text","text":" I","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" should","reasoning_details":[{"type":"reasoning.text","text":" should","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" present","reasoning_details":[{"type":"reasoning.text","text":" present","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" this","reasoning_details":[{"type":"reasoning.text","text":" this","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" information","reasoning_details":[{"type":"reasoning.text","text":" information","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" clearly","reasoning_details":[{"type":"reasoning.text","text":" clearly","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.text","text":" to","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.text","text":" the","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.text","text":" user","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.text","text":".","format":"unknown","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"\n","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"The","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" weather","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" in","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" Florence","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":",","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" Italy","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" is","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" currently","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" ","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"40","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"°C","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" (","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"104","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"°F","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":").","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" That","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"'s","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" quite","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" hot","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" weather","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" -","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" you","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"'ll","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" want","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" to","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" stay","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" hydrated","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" and","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" seek","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" shade","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" if you","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"'re","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" planning","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" to","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" be","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":" outdoors","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"!","reasoning":null,"reasoning_details":[]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[]},"finish_reason":"stop","native_finish_reason":"stop","logprobs":null}],"system_fingerprint":""}
+
+ data: {"id":"gen-1761052918-ETUf38GqhLQg9cxY9999","provider":"Novita","model":"z-ai/glm-4.6","object":"chat.completion.chunk","created":1761052918,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":219,"completion_tokens":84,"total_tokens":303,"cost":0.00020938,"is_byok":false,"prompt_tokens_details":{"cached_tokens":218,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00002458,"upstream_inference_completions_cost":0.0001848},"completion_tokens_details":{"reasoning_tokens":49,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 745.263083ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterThinking/glm-4.6/thinking.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/glm-4.6/thinking.yaml
new file mode 100644
index 000000000..2e0663f25
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/glm-4.6/thinking.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 494
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"z-ai/glm-4.6","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n{\"id\":\"gen-1761052911-sbgCD9CtzdJVSkSMnnAe\",\"provider\":\"BaseTen\",\"model\":\"z-ai/glm-4.6\",\"object\":\"chat.completion\",\"created\":1761052911,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\\nI'll check the weather in Florence, Italy for you.\\n\",\"refusal\":null,\"reasoning\":\"The user is asking for weather information for Florence, Italy. I have access to a weather function that takes a location parameter. The user has provided \\\"Florence, Italy\\\" as the location. I should use this exact location string when calling the weather function.\",\"tool_calls\":[{\"index\":0,\"id\":\"chatcmpl-tool-340de3c29804485e8d45a5742b77a0b5\",\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\": \\\"Florence, Italy\\\"}\"}}]}}],\"system_fingerprint\":null,\"usage\":{\"prompt_tokens\":187,\"completion_tokens\":83,\"total_tokens\":270,\"cost\":0.0002948,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0001122,\"upstream_inference_completions_cost\":0.0001826},\"completion_tokens_details\":{\"reasoning_tokens\":66,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 541.844291ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 848
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"content":"\nI''ll check the weather in Florence, Italy for you.\n","tool_calls":[{"id":"chatcmpl-tool-340de3c29804485e8d45a5742b77a0b5","function":{"arguments":"{\"location\": \"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"chatcmpl-tool-340de3c29804485e8d45a5742b77a0b5","role":"tool"}],"model":"z-ai/glm-4.6","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761052913-qCEYOs6jhn3hOyFZslYW\",\"provider\":\"Novita\",\"model\":\"z-ai/glm-4.6\",\"object\":\"chat.completion\",\"created\":1761052913,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\\n\\nThe current weather in Florence, Italy is 40°C (104°F), which is quite hot! It's a very warm day there.\",\"refusal\":null,\"reasoning\":\"The weather function returned \\\"40 C\\\" for Florence, Italy. This indicates that the current temperature in Florence is 40 degrees Celsius, which is quite hot - about 104 degrees Fahrenheit. I should present this information clearly to the user.\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"The weather function returned \\\"40 C\\\" for Florence, Italy. This indicates that the current temperature in Florence is 40 degrees Celsius, which is quite hot - about 104 degrees Fahrenheit. I should present this information clearly to the user.\",\"format\":\"unknown\",\"index\":0}]}}],\"system_fingerprint\":\"\",\"usage\":{\"prompt_tokens\":219,\"completion_tokens\":81,\"total_tokens\":300,\"cost\":0.00028853,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":43,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00011033,\"upstream_inference_completions_cost\":0.0001782},\"completion_tokens_details\":{\"reasoning_tokens\":61,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 924.882291ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterThinking/gpt-5/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/gpt-5/thinking-streaming.yaml
new file mode 100644
index 000000000..b86d810d6
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/gpt-5/thinking-streaming.yaml
@@ -0,0 +1,311 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 548
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"openai/gpt-5","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"**Retr","reasoning_details":[{"type":"reasoning.summary","summary":"**Retr","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ieving","reasoning_details":[{"type":"reasoning.summary","summary":"ieving","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.summary","summary":" weather","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.summary","summary":" for","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.summary","summary":" Florence","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"**\n\nI","reasoning_details":[{"type":"reasoning.summary","summary":"**\n\nI","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" need","reasoning_details":[{"type":"reasoning.summary","summary":" need","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.summary","summary":" to","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" respond","reasoning_details":[{"type":"reasoning.summary","summary":" respond","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.summary","summary":" to","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user's","reasoning_details":[{"type":"reasoning.summary","summary":" user's","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" question","reasoning_details":[{"type":"reasoning.summary","summary":" question","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" about","reasoning_details":[{"type":"reasoning.summary","summary":" about","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.summary","summary":" weather","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" in","reasoning_details":[{"type":"reasoning.summary","summary":" in","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.summary","summary":" Florence","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Italy","reasoning_details":[{"type":"reasoning.summary","summary":" Italy","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" To","reasoning_details":[{"type":"reasoning.summary","summary":" To","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" do","reasoning_details":[{"type":"reasoning.summary","summary":" do","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" this","reasoning_details":[{"type":"reasoning.summary","summary":" this","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"āll","reasoning_details":[{"type":"reasoning.summary","summary":"āll","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" use","reasoning_details":[{"type":"reasoning.summary","summary":" use","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.summary","summary":" weather","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" tool","reasoning_details":[{"type":"reasoning.summary","summary":" tool","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" to","reasoning_details":[{"type":"reasoning.summary","summary":" to","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" get","reasoning_details":[{"type":"reasoning.summary","summary":" get","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" information","reasoning_details":[{"type":"reasoning.summary","summary":" information","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" needed","reasoning_details":[{"type":"reasoning.summary","summary":" needed","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Even","reasoning_details":[{"type":"reasoning.summary","summary":" Even","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" though","reasoning_details":[{"type":"reasoning.summary","summary":" though","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" developer","reasoning_details":[{"type":"reasoning.summary","summary":" developer","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" tools","reasoning_details":[{"type":"reasoning.summary","summary":" tools","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" allow","reasoning_details":[{"type":"reasoning.summary","summary":" allow","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.summary","summary":" for","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" running","reasoning_details":[{"type":"reasoning.summary","summary":" running","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" multiple","reasoning_details":[{"type":"reasoning.summary","summary":" multiple","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" tools","reasoning_details":[{"type":"reasoning.summary","summary":" tools","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" just","reasoning_details":[{"type":"reasoning.summary","summary":" just","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" need","reasoning_details":[{"type":"reasoning.summary","summary":" need","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" one","reasoning_details":[{"type":"reasoning.summary","summary":" one","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.summary","summary":" for","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" this","reasoning_details":[{"type":"reasoning.summary","summary":" this","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" task","reasoning_details":[{"type":"reasoning.summary","summary":" task","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" So","reasoning_details":[{"type":"reasoning.summary","summary":" So","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"āll","reasoning_details":[{"type":"reasoning.summary","summary":"āll","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" call","reasoning_details":[{"type":"reasoning.summary","summary":" call","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" functions","reasoning_details":[{"type":"reasoning.summary","summary":" functions","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".weather","reasoning_details":[{"type":"reasoning.summary","summary":".weather","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" with","reasoning_details":[{"type":"reasoning.summary","summary":" with","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" location","reasoning_details":[{"type":"reasoning.summary","summary":" location","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.summary","summary":" \"","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"Flor","reasoning_details":[{"type":"reasoning.summary","summary":"Flor","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"ence","reasoning_details":[{"type":"reasoning.summary","summary":"ence","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Italy","reasoning_details":[{"type":"reasoning.summary","summary":" Italy","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".\"","reasoning_details":[{"type":"reasoning.summary","summary":".\"","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" After","reasoning_details":[{"type":"reasoning.summary","summary":" After","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" that","reasoning_details":[{"type":"reasoning.summary","summary":" that","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I'll","reasoning_details":[{"type":"reasoning.summary","summary":" I'll","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" check","reasoning_details":[{"type":"reasoning.summary","summary":" check","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" response","reasoning_details":[{"type":"reasoning.summary","summary":" response","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" and","reasoning_details":[{"type":"reasoning.summary","summary":" and","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" ensure","reasoning_details":[{"type":"reasoning.summary","summary":" ensure","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" handle","reasoning_details":[{"type":"reasoning.summary","summary":" handle","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" it","reasoning_details":[{"type":"reasoning.summary","summary":" it","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" properly","reasoning_details":[{"type":"reasoning.summary","summary":" properly","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Let's","reasoning_details":[{"type":"reasoning.summary","summary":" Let's","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" move","reasoning_details":[{"type":"reasoning.summary","summary":" move","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" forward","reasoning_details":[{"type":"reasoning.summary","summary":" forward","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"!","reasoning_details":[{"type":"reasoning.summary","summary":"!","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.encrypted","data":"gAAAAABo95Axc714cUMJItsXPQrhNJR2obx_YXqIn0SQS-gE8g4lh5sTeHrkb721BilEYlBCOBXFVH17a3-fyrvXslOaCj7CJUH2BRg5Fbov1hAWBZVMeo5feIY57920EPdtkKtMF4UWFYuUEBCliqbN2y_E3amMQTmO_78QsrnYKaI4zd0z0szvOXK963muw4mfySk8nPbHQdlU7Yt2kXqYnedfKMRG0ojFSAFcD5XcHw8uGxPPuCX95gGDCP53gKIpir57bFrx8x1TJ9PNZqtKynEadPcYTEoxP4ioSn_2Oob11nVF2BNCZkOt9MUr8XIMSGM7XgyhmrBGY3RGoVfS72yf7MiDrz_0SUaBNro-G4BpH9zSKcvBGnRN-xJiHHhghqowSSnf2PftEnKR5eWm5NB-3X0wUzMIMlb8u59qiF24IG6DK6aoqRccgI6xl8BWKeceyvBRO28N7EhQt3nzEQ106d3CBd_1MYbgs3PCnyDc17CsSV79lIFIpInigRgO9Di_YKfZxy-PVfa2R9bLa37vVgZU7gW_U8oCl_wYgFREmf0-rbMCIE8QCftAtjKqLmY1dqk7uA1yan8UHwz4KMSPRHTRXtTbMLCOvjWe0Ryfk3IcJ0EBJc4D6iYuBiSKkpAC7qXm9OV85Mvn135eyxWZxMGW-aGvY3dTTPU3QVied8DZ7DDXcx6Hu77FxVmZylMUpyPVUtrReJBGQHmLfLOa-VEsyEDUpqOiU4HiwlJQMIdPjVa4Ew5IB4LTyhcv_Sl98soc6xfo3lPA17X8xALHLgX9igzoVpPCUzWDic7LmPuaVveW_zQrkiPn2502jKOr-9Yd-uNpRA9cnhCtqfzMlAZ0jsUpNZj2rC5S0GAptnogLGsrY5jh_Q9hSdOYi_CI8eCaMlWEZulrQtDF0hO7jackASXplQcYElyN0GOtDxh2PIM9dQUrx8ai1RzssrunsVpMtAy-N7bNQPGrwRKFT2qfkL2m65rYP7vi_E5D__dVzgA8j-T1HpSHb6RWeHRU-O5CftPwUbaZHWcg2KEKZBUjrkT_fRvbaWPIDUbimKf5hDOUxbDQbAqLVG23_QblWxVRwwYRfx-e8Teq7TMW34_roR72VTVoH9-qMrpqB2f6Rv6zbBA7WfM28Izo-2zGFMQMxHUhmGLKCpZW62ayE4CbrgTJoT_zuwtzlMI9m_Wavff7Ke54nUAs3WRtGpIS78JgkGogV4Ynol8FGLR8rFJ-geeVK6cwLK5owvSzzioOycA4IME4ic56VV5DWBWlMe0hLnAw1rNK0EkPD80e308Tlw5V0QaqJL6mWACp1OZPD4UWCBpU807GNNKJhCbRG1WzFrI9l3WlstQVfb4O6sOvqeKpcxbdKZxTfu7DG7IgmSCMoeWEgftSW7ndCDdOTlRjYXzQFu-WNk5tF533M6y_ZwmhVOy-79PJQqf44293fcPaF7wqlRpWW6gr1RNq7f0dUwxMhkhlZefYJhJYLAGVPuCw9ST4DyRzMqgUcu3BIQ_m9zomNyH3t7S6oM5jKSDN5ewUpdvYWGxXji6bFasGZsLL26mPQvTKruTIDOjU-WD5NOTRvq3bZfZStZHNNBDpZtzGXlAWG_e_Snf-uJNJMFogRNhnjSH5mhnsOG3rvdo=","id":"rs_0e2b6966875e996f0168f7902c91c88196abe59d1af22f2f30","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"call_ZflTiDdr9FEj8wy7gCbD4gTQ","index":0,"type":"function","function":{"name":"weather","arguments":""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"{\""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"location"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"\":\""}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"Flor"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"ence"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":","}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":" Italy"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"type":"function","function":{"arguments":"\"}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"tool_calls","native_finish_reason":"completed","logprobs":null}]}
+
+ data: {"id":"gen-1761054763-a10nm1pcIKLo1lEHAAjM","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054763,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":66,"completion_tokens":86,"total_tokens":152,"cost":0.0009425,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000825,"upstream_inference_completions_cost":0.00086},"completion_tokens_details":{"reasoning_tokens":64,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 566.377ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 3151
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"call_ZflTiDdr9FEj8wy7gCbD4gTQ","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"openai-responses-v1","index":0,"summary":"**Retrieving weather for Florence**\n\nI need to respond to the user''s question about the weather in Florence, Italy. To do this, Iāll use the weather tool to get the information needed. Even though the developer tools allow for running multiple tools, I just need one for this task. So, Iāll call functions.weather with the location \"Florence, Italy.\" After that, I''ll check the response and ensure I handle it properly. Let''s move forward!","type":"reasoning.summary"},{"data":"gAAAAABo95Axc714cUMJItsXPQrhNJR2obx_YXqIn0SQS-gE8g4lh5sTeHrkb721BilEYlBCOBXFVH17a3-fyrvXslOaCj7CJUH2BRg5Fbov1hAWBZVMeo5feIY57920EPdtkKtMF4UWFYuUEBCliqbN2y_E3amMQTmO_78QsrnYKaI4zd0z0szvOXK963muw4mfySk8nPbHQdlU7Yt2kXqYnedfKMRG0ojFSAFcD5XcHw8uGxPPuCX95gGDCP53gKIpir57bFrx8x1TJ9PNZqtKynEadPcYTEoxP4ioSn_2Oob11nVF2BNCZkOt9MUr8XIMSGM7XgyhmrBGY3RGoVfS72yf7MiDrz_0SUaBNro-G4BpH9zSKcvBGnRN-xJiHHhghqowSSnf2PftEnKR5eWm5NB-3X0wUzMIMlb8u59qiF24IG6DK6aoqRccgI6xl8BWKeceyvBRO28N7EhQt3nzEQ106d3CBd_1MYbgs3PCnyDc17CsSV79lIFIpInigRgO9Di_YKfZxy-PVfa2R9bLa37vVgZU7gW_U8oCl_wYgFREmf0-rbMCIE8QCftAtjKqLmY1dqk7uA1yan8UHwz4KMSPRHTRXtTbMLCOvjWe0Ryfk3IcJ0EBJc4D6iYuBiSKkpAC7qXm9OV85Mvn135eyxWZxMGW-aGvY3dTTPU3QVied8DZ7DDXcx6Hu77FxVmZylMUpyPVUtrReJBGQHmLfLOa-VEsyEDUpqOiU4HiwlJQMIdPjVa4Ew5IB4LTyhcv_Sl98soc6xfo3lPA17X8xALHLgX9igzoVpPCUzWDic7LmPuaVveW_zQrkiPn2502jKOr-9Yd-uNpRA9cnhCtqfzMlAZ0jsUpNZj2rC5S0GAptnogLGsrY5jh_Q9hSdOYi_CI8eCaMlWEZulrQtDF0hO7jackASXplQcYElyN0GOtDxh2PIM9dQUrx8ai1RzssrunsVpMtAy-N7bNQPGrwRKFT2qfkL2m65rYP7vi_E5D__dVzgA8j-T1HpSHb6RWeHRU-O5CftPwUbaZHWcg2KEKZBUjrkT_fRvbaWPIDUbimKf5hDOUxbDQbAqLVG23_QblWxVRwwYRfx-e8Teq7TMW34_roR72VTVoH9-qMrpqB2f6Rv6zbBA7WfM28Izo-2zGFMQMxHUhmGLKCpZW62ayE4CbrgTJoT_zuwtzlMI9m_Wavff7Ke54nUAs3WRtGpIS78JgkGogV4Ynol8FGLR8rFJ-geeVK6cwLK5owvSzzioOycA4IME4ic56VV5DWBWlMe0hLnAw1rNK0EkPD80e308Tlw5V0QaqJL6mWACp1OZPD4UWCBpU807GNNKJhCbRG1WzFrI9l3WlstQVfb4O6sOvqeKpcxbdKZxTfu7DG7IgmSCMoeWEgftSW7ndCDdOTlRjYXzQFu-WNk5tF533M6y_ZwmhVOy-79PJQqf44293fcPaF7wqlRpWW6gr1RNq7f0dUwxMhkhlZefYJhJYLAGVPuCw9ST4DyRzMqgUcu3BIQ_m9zomNyH3t7S6oM5jKSDN5ewUpdvYWGxXji6bFasGZsLL26mPQvTKruTIDOjU-WD5NOTRvq3bZfZStZHNNBDpZtzGXlAWG_e_Snf-uJNJMFogRNhnjSH5mhnsOG3rvdo=","format":"openai-responses-v1","id":"rs_0e2b6966875e996f0168f7902c91c88196abe59d1af22f2f30","index":0,"type":"reasoning.encrypted"}]},{"content":"40 C","tool_call_id":"call_ZflTiDdr9FEj8wy7gCbD4gTQ","role":"tool"}],"model":"openai/gpt-5","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.encrypted","data":"gAAAAABo95A0iap0c8f9yFG1ELhpsd5_C_6APWh4LteSdKsUt7BEpwkmSEd_TLNHxyjR0kBAZGMQSa3uUyPjKfUFVK91DBArZsxe5QKcaMhxSS-ey4_yfMYdnV2ecAde4biBS_ULm77sfLQCuICS6RrPvuszQtIJjiB0xM8On7OzGoiQk7zOmOBP3mEl3gSVMrawhapK3Y9GxVSvEoi3_nbl4E7Sbr5bH3e7pNm6Od4f2uG9cX-8XUzrOVtrHd5KiCty5moxezDMYjnTkZJvb0ByuU-RRAHDzvIK-eUSLs9Z_P-h-B-btPgpf2yVmYR0BsseB3CGp130KtZ6hP107Tlm9JUy_Vo39ib18A_20NCVI3RkohuriBL-2TUZziJRhRfGM99yoBsK1xQ_uF2pgSLHxEFobLiyz1NtcqprQoQ4WJ5jzAlJ7dTIjR6tegYKrlvbklU_2RyeBQoDHDUEzb8SOdRgUNMelEU0NSqH26LGZMQ5poykfKMcInsLMVelpoweKCIJehvv46--wx4xo072OYsvNtO0nUgjG9QDh1HWpad8gltd2sUPk_NLbswLSU5eyuNiiLF1CGsaZSC4I5hn9eoDT0P4sWnYUB3okaIlbDWFLlyf1KqpszCsaIJwmwRmjjO42zgwdhRfOwTRp8mbyrYrUSwMoGdbCZYOS3Ll-Ee9ZRubG2fHRG-xakvjjOAamEMt4oZ6PkiaZtmglXPlu6UHr7r8MDoJ2_BqPpzLkV3NWo6Vx5L1NbI0ocC0UKPusftS8QbukZclSAEf5GHKwZZfce7RtLr7UN8butJgD5mHUXNEXXgGbz-8S4PoLCydi9gqT0SsnmvCULB7VMArnyMWa61qp8QgOhCYyz1VnlH65LDUSEtoMsdOfERGNpg3WSBbSTOBO5uBXNp5Vzh2wAc3xQszHjJoVtPEfEOM729ZpTH4xH4-3ON4aSlWLrCODTB_3sH1g5jXE39-fdFiL_2X5cPPBGvFXFrR5MSxrPzA6Cij26tenBfQMaf0S4FBM_lzIRJK-QPV76-Kh7GRU2MJM3z04LnvypXoxOGmmEGHB10QBAsNN1HwMp-LVFKpDIN9YO22pRZTOfsxdHUO8ddvCEWKLavldSvXsMMKGS_JTpIT_jXs6aiwNippc76vIWolky8REeCu77K1o_-u4fN0Un4I0TMo_S_xR6hx78BWXECDknUywgyZmoChB0xq8dqKgPw2tzQHGum4DBUEKjvvziTwP2Ouifri5k1_d0cayyDCX29QDESQzALC-lPr5TbEnv5bJ8QefGnfCBtModtRcb2JVloXKcA9jccqmRy02q941o95P17Sp0m_asQDw7iVpNZLYS_ShmSvnkEi8Yv_gatqk73jR2d84fuNFoRV1AcssKSgZNr0WFvi1y6qdlm3Dm-n8kvWiuTJFAsJeTuO70fsM07QmPq4y3DeuaBV5Ul-OaHr-LCbpeIQnHgcG39oAecim7JU5ZOXmSafgTMB7zuPaqWp_wfXenvojgCrodro25SYjgDRsVnZMxzav9guWcDlF6SD-zQP47ZSPelZy9CN3QnSliyEpsoTTN67hpq4aEaZNfjOLizAtmIL-ilLHYC_uouy4C5NeWue5pp1AsfdOknDDRIUoWcqF4zRMUfn0Vynw0jIHT2YH7xj3wDWEcaATEW1LnhUib-rt5i5VgaHXTmN1GzRic9zkizvN3_BVOQ=","id":"rs_0e2b6966875e996f0168f79032628c8196bb355126c34b8dfa","format":"openai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":"It"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":"ās"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":" currently"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":" about"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":"40"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":"°C"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":" ("},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":"104"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":"°F"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":")"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":" in"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":" Florence"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":","},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":" Italy"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":"."},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"completed","logprobs":null}]}
+
+ data: {"id":"gen-1761054769-wtmJGmVg9GV3qS74TqVu","provider":"OpenAI","model":"openai/gpt-5","object":"chat.completion.chunk","created":1761054769,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":219,"completion_tokens":150,"total_tokens":369,"cost":0.00177375,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00027375,"upstream_inference_completions_cost":0.0015},"completion_tokens_details":{"reasoning_tokens":128,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 605.446ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterThinking/gpt-5/thinking.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/gpt-5/thinking.yaml
new file mode 100644
index 000000000..5b14f8f33
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/gpt-5/thinking.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 494
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"openai/gpt-5","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054752-Z3PQgjaQed4rJTsn3RYa\",\"provider\":\"OpenAI\",\"model\":\"openai/gpt-5\",\"object\":\"chat.completion\",\"created\":1761054752,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"completed\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":\"**Fetching weather data**\\n\\nI need to get the weather info. The user asked, \\\"What's the weather in Florence, Italy?\\\" so I should use the weather function for that. Thereās a multi-tool option available, but we only need one tool here. I'll call functions.weather with \\\"Florence, Italy\\\" as the location. After I receive the result, Iāll give the user a clear and concise answer, focusing on the key details like temperature and conditions, even though I'm unsure what the tool will return.\",\"tool_calls\":[{\"id\":\"call_JH16IMSaSHLE7oICZRQzDvLH\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"**Fetching weather data**\\n\\nI need to get the weather info. The user asked, \\\"What's the weather in Florence, Italy?\\\" so I should use the weather function for that. Thereās a multi-tool option available, but we only need one tool here. I'll call functions.weather with \\\"Florence, Italy\\\" as the location. After I receive the result, Iāll give the user a clear and concise answer, focusing on the key details like temperature and conditions, even though I'm unsure what the tool will return.\",\"format\":\"openai-responses-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"gAAAAABo95AlHDFCURxQFvbG5EJbGKJL25nSD5sieM-GXHlCv12f1ehmOOO8Tl6qqWcJO2c4G8YSrEu0mjlM43EGB-PKd-FA6M2B04NDNY4Q8bW6NULmWm6ZfHr8GXncCAddcdStbfz3sCRjJe-vqPN2OXLjCy6eYjjR2EKsmFUNG80TL3cSaDoZ9vCKUWXgUBzZ-8scHgLDI3USCAiwiDu0BWeC5-IfdiAQr54ZXk_pxZdesRjHnZlUfg2SLCo6X65hC02w9yKTwtTsg71S33bnjhMNXaIx4zSf8txF3Jt_BdS08fnjj3kCOZog2hvn8FLUGTVwARfm87zxveegUYFunxzpbJnP6PXZCQyYVVp16mGdtAKn1SPtFghKBakOTYAyXc4-oJMu0_cDX29G9LFwo1rHSRp48kSRYvyIkNtaox_sRCf2fVE2lJsn0B69V1kJZAHTUP8LuMZcx5ArObW5znf_c22HWCDv1LEMvPU1RfDBDUAbt2DiIr5QyAvDo08gW_n_rm1cGgM7H0iLdS_ecrI2FED0Bj0fmPlBlkr9yW1RJ8gwM_5f87-P79OH4RL_o6RBFocEEdy55xtTNK52XrKoti9-W-8nQg3Vn2X4ItI_90P7FARE_LPH63O38QtCoLllyGFMvYurkthtwlsvpUgNL9QlVrsmoBJjNRYaEyDJGw6lmz_uc3RWYGU0rAJuUpzIwm3ZBN4bkRanmgpLCvpixsq6iH3pj2Hwz3EVHGX07eZCBLp0Xn6Kk_7eGRF7HHJHfrF3kQehWi9jfCq6WoWt9LHIwS2WOHQ37-RVP5IJ5CS1zFp93fYyXjqXXghwu32PwJz6uJiwIciPkSWS-X7wt3evn67VPUaezVSzXud7TgNOCRrOaFUYE_WYTTumvxGzIH2TwQQRgsY61MyuvIRMncEjFLYDh_EiYbih8PJE0STK2Uni5UzoU8j9VGrlulzUIA-4CcvojmLaTiUKue2CXp5jlhZcmuZ7KIuXu12QRSoTlCzHWA0qPYhtjT57IVhNO5SKd6Bg3VPJ1QJsS8ndwUFlOJNo_onsdJ7NDHTrnhX18SHhD9xojO2jtIna7lWa2FUMt3lNsL0pqGrOYD2PJ0rAJTcdKl_6Q0ECHn09xaMhoKScStleB9U7rNVKmpjkFrSl_6mprtQCTQPE7Ovjt4bF5js5DjbdXbCEAeiy2-KPs0ET_-kMYkrCsxh7ELNIxPsaf01JL4YpkYsuzCHV0VZRHaMq0DBQcq2OxpmE5doeomMi6fMgoq8d_jTNhpR2jJ8qblQQ6aQqLLJZc921ougvrupAo1MCdV1JI9yIgkNvc_Q-WKCpCSzV39O_QBD62VvgjWrbYf_t0BlUqDh6866b92fG75kpjZqCXIdb70cLC9cgmyfohVqN9-LBWWSBw4KHCWj3m6jqkkc9htN5gt1lQYQMtXyWmTTV83NnTIbfZq43JfyhwWaMMnMYfrUVflirJ6_8lMTAQeloThWdQQymaeMOJXIXTx-gl0_fbVG8Im7ZaFiqXzYrNWgw9iPK1kvmeZmMIkTTZVdpDToBEuQ4qeoczsmqOspVLC7yf0USoL2HNl3nTJaiRvYwRAzbSwjV\",\"id\":\"rs_07508cdfb87721800168f79020d93c819589fabd1b4a45c9e0\",\"format\":\"openai-responses-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":66,\"completion_tokens\":86,\"total_tokens\":152,\"cost\":0.0009425,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000825,\"upstream_inference_completions_cost\":0.00086},\"completion_tokens_details\":{\"reasoning_tokens\":64,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 341.906ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 3103
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"call_JH16IMSaSHLE7oICZRQzDvLH","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"openai-responses-v1","index":0,"summary":"**Fetching weather data**\n\nI need to get the weather info. The user asked, \"What''s the weather in Florence, Italy?\" so I should use the weather function for that. Thereās a multi-tool option available, but we only need one tool here. I''ll call functions.weather with \"Florence, Italy\" as the location. After I receive the result, Iāll give the user a clear and concise answer, focusing on the key details like temperature and conditions, even though I''m unsure what the tool will return.","type":"reasoning.summary"},{"data":"gAAAAABo95AlHDFCURxQFvbG5EJbGKJL25nSD5sieM-GXHlCv12f1ehmOOO8Tl6qqWcJO2c4G8YSrEu0mjlM43EGB-PKd-FA6M2B04NDNY4Q8bW6NULmWm6ZfHr8GXncCAddcdStbfz3sCRjJe-vqPN2OXLjCy6eYjjR2EKsmFUNG80TL3cSaDoZ9vCKUWXgUBzZ-8scHgLDI3USCAiwiDu0BWeC5-IfdiAQr54ZXk_pxZdesRjHnZlUfg2SLCo6X65hC02w9yKTwtTsg71S33bnjhMNXaIx4zSf8txF3Jt_BdS08fnjj3kCOZog2hvn8FLUGTVwARfm87zxveegUYFunxzpbJnP6PXZCQyYVVp16mGdtAKn1SPtFghKBakOTYAyXc4-oJMu0_cDX29G9LFwo1rHSRp48kSRYvyIkNtaox_sRCf2fVE2lJsn0B69V1kJZAHTUP8LuMZcx5ArObW5znf_c22HWCDv1LEMvPU1RfDBDUAbt2DiIr5QyAvDo08gW_n_rm1cGgM7H0iLdS_ecrI2FED0Bj0fmPlBlkr9yW1RJ8gwM_5f87-P79OH4RL_o6RBFocEEdy55xtTNK52XrKoti9-W-8nQg3Vn2X4ItI_90P7FARE_LPH63O38QtCoLllyGFMvYurkthtwlsvpUgNL9QlVrsmoBJjNRYaEyDJGw6lmz_uc3RWYGU0rAJuUpzIwm3ZBN4bkRanmgpLCvpixsq6iH3pj2Hwz3EVHGX07eZCBLp0Xn6Kk_7eGRF7HHJHfrF3kQehWi9jfCq6WoWt9LHIwS2WOHQ37-RVP5IJ5CS1zFp93fYyXjqXXghwu32PwJz6uJiwIciPkSWS-X7wt3evn67VPUaezVSzXud7TgNOCRrOaFUYE_WYTTumvxGzIH2TwQQRgsY61MyuvIRMncEjFLYDh_EiYbih8PJE0STK2Uni5UzoU8j9VGrlulzUIA-4CcvojmLaTiUKue2CXp5jlhZcmuZ7KIuXu12QRSoTlCzHWA0qPYhtjT57IVhNO5SKd6Bg3VPJ1QJsS8ndwUFlOJNo_onsdJ7NDHTrnhX18SHhD9xojO2jtIna7lWa2FUMt3lNsL0pqGrOYD2PJ0rAJTcdKl_6Q0ECHn09xaMhoKScStleB9U7rNVKmpjkFrSl_6mprtQCTQPE7Ovjt4bF5js5DjbdXbCEAeiy2-KPs0ET_-kMYkrCsxh7ELNIxPsaf01JL4YpkYsuzCHV0VZRHaMq0DBQcq2OxpmE5doeomMi6fMgoq8d_jTNhpR2jJ8qblQQ6aQqLLJZc921ougvrupAo1MCdV1JI9yIgkNvc_Q-WKCpCSzV39O_QBD62VvgjWrbYf_t0BlUqDh6866b92fG75kpjZqCXIdb70cLC9cgmyfohVqN9-LBWWSBw4KHCWj3m6jqkkc9htN5gt1lQYQMtXyWmTTV83NnTIbfZq43JfyhwWaMMnMYfrUVflirJ6_8lMTAQeloThWdQQymaeMOJXIXTx-gl0_fbVG8Im7ZaFiqXzYrNWgw9iPK1kvmeZmMIkTTZVdpDToBEuQ4qeoczsmqOspVLC7yf0USoL2HNl3nTJaiRvYwRAzbSwjV","format":"openai-responses-v1","id":"rs_07508cdfb87721800168f79020d93c819589fabd1b4a45c9e0","index":0,"type":"reasoning.encrypted"}]},{"content":"40 C","tool_call_id":"call_JH16IMSaSHLE7oICZRQzDvLH","role":"tool"}],"model":"openai/gpt-5","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"reasoning":{"effort":"medium"}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054757-RbtfcOpaiHHf2DnYJ33c\",\"provider\":\"OpenAI\",\"model\":\"openai/gpt-5\",\"object\":\"chat.completion\",\"created\":1761054757,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"completed\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"Itās about 40°C (104°F) in Florence right now. Would you like details like conditions or a forecast?\",\"refusal\":null,\"reasoning\":\"**Providing weather information**\\n\\nThe tool returned a temperature of 40°C, which is pretty hot! I think it's important to present weather information concisely. While I could mention conditions like sunny or cloudy, I can't make those up since the tool only provided the temperature. So, Iāll state: \\\"The current temperature in Florence, Italy is about 40°C (104°F).\\\" It's useful to include a note about heat safety if appropriate. If the user wants more details or conditions, I can ask!\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"**Providing weather information**\\n\\nThe tool returned a temperature of 40°C, which is pretty hot! I think it's important to present weather information concisely. While I could mention conditions like sunny or cloudy, I can't make those up since the tool only provided the temperature. So, Iāll state: \\\"The current temperature in Florence, Italy is about 40°C (104°F).\\\" It's useful to include a note about heat safety if appropriate. If the user wants more details or conditions, I can ask!\",\"format\":\"openai-responses-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"gAAAAABo95ArxowPkxbCcPUAtMhlYexdVBDsZUDEKxDswE061QLWPQ5fhlipc3Shqpt5ebOISswND7zpx7un6-_WOis7bxZLbXatlvUGwnamND-IobPomP0QHlAJmrOFp478nTQFGfK1FUChsLBArCVR1XXMzi9-3Cv-CHTDIZcRblIrxidZdUj2mApj7JsU86gE02sVgL9xn5ehZBiQUdnig817Gul0meR7S3xDf473E2SPfzy4dCuk_cMXfoJ64vEVxPEyWljVkxOIauXqJjNHBDpILktjQP9yl-YZbMzqRqdyG3biRpdIIP2dcg8MfMMAP03atNPsyqEmSMY7Rjdr1K-cmlWfjcqyn4v38T0dQmUIov8VaLdnICQ53Tg6ghQGiQBsuKNPoAUJqQwvaznht_FNArMgcRjA3_tm9eNVCU26KZjNneywUX1x-p1EgZ6JAaCA2lUVx8Z2IMlrfF4w6f_QTdESjhf2-kQSXEkhSoAyz_NPr5-Y8ea69V_Iey2UDgz2dBeVRnntuE_uYGfCcyfDF5y3FAP0Ja4SjGWgWJjVsd8nR40oZWgdoIN-VbKPyAB_nG1armr_rfcmjODIWAlOQk4BxvzJNaJdcam7ylbVD-tKoDv8TNqKe-6oM9U03jQLw0VwVO7wDMtJ66Gzr9FeMKcflnc3gPA9zS8QJsC4OyavZyO6yyIuXJn6NSvklQYNrE4rnUlJXtw9HuFNYmK80JJpl7pc8YP42A_xFem0v6vozbzOM5-47icxLtx4BZvD73npFJI_hwkK7RhGGPdIVzLTxo9lajlGu__i5udg8nKazrZKdVUiFU2gorvqPvPcPMt1cSyXsOQLXvP9VsEMgc9-M--Gi6PS8o5qKPq5kWD7FWE8hSp3AQwS6rJniivVuBYLfZ3GLgxbVPXNXYBKMgzzfJnJlqBFTaG4IBhRHRQdR7Y5c6cSncoWZ3E7dT37PnIRZ65TW3xD2Xhyp2UuLgkd_Cf6QNBfCm8dsukXEE77z8xLgdIJoq0OkwNbW6_Qc6gyJAADM0sk9XUJ3B6esqB8KZcixF4QnHmhm_y8I1RGpDUQyd8moE3wbKf7-HhfiBOlwqUG-BaaZ5Os3Kk5zg4ka1k4LV1v36Nk8cWIhMVJbGVMsUPJsq3I4vhgRX8CnZ0RmKH4N5sLpscZtTtOLm17adbnuiw7a7zRbcRLV54g4Yf0-FDDjz43QCwsUZ95QW8JX71o9pWdEu27tdCCMfD_aC-CWYpVHW_YoYTq6nKGhlJCBeigDXYwyKJhOHcNMgJUB9iXv3bGVovOtGRjoyDgTBuM_z0Krz2eX1aJncwz7x2Uf0wgvcHfMWZQNjDUPs8a8QawTAu7izSEtVwh8WXo851kaiK5BxmCuQ8ZezO27cn8Yw3tMD-oTFyvoJy6BRhW9c-0jzsqaopUIoZUYrtKEQDwrGB0OjVlQykuqxpVov7Nr4FP6hFTds1Z26vhVI9B0FBMtrsOKwqyVf8TwE53g3gSaFRrMLgART8xca_n3uT_44sNUrqITd1xX_iOzwrFng1-jlEYZ0WA0k4jPh_OS5kTzT_OgE3YB-cXwcTf1h0SgNN54bk4Mivmx_9lqDyTv0ArJfZ9KYjvs3R4syhvwL6aMxE9NHQwKsnoUSI2NBa15LYqSBNnNpDoPxCl8zTXZNVKlWdAFXFLIXli0WishQ==\",\"id\":\"rs_07508cdfb87721800168f7902635048195a6af3183d6deb8ed\",\"format\":\"openai-responses-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":215,\"completion_tokens\":159,\"total_tokens\":374,\"cost\":0.00185875,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00026875,\"upstream_inference_completions_cost\":0.00159},\"completion_tokens_details\":{\"reasoning_tokens\":128,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 539.821458ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterThinking/grok-code-fast-1/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/grok-code-fast-1/thinking-streaming.yaml
new file mode 100644
index 000000000..2f73e8f74
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/grok-code-fast-1/thinking-streaming.yaml
@@ -0,0 +1,249 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 557
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"x-ai/grok-code-fast-1","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"The","reasoning_details":[{"type":"reasoning.summary","summary":"The","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.summary","summary":" user","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" asked","reasoning_details":[{"type":"reasoning.summary","summary":" asked","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" for","reasoning_details":[{"type":"reasoning.summary","summary":" for","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.summary","summary":" weather","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" in","reasoning_details":[{"type":"reasoning.summary","summary":" in","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.summary","summary":" Florence","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Italy","reasoning_details":[{"type":"reasoning.summary","summary":" Italy","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" have","reasoning_details":[{"type":"reasoning.summary","summary":" have","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.summary","summary":" a","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" tool","reasoning_details":[{"type":"reasoning.summary","summary":" tool","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" called","reasoning_details":[{"type":"reasoning.summary","summary":" called","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.summary","summary":" \"","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"weather","reasoning_details":[{"type":"reasoning.summary","summary":"weather","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\"","reasoning_details":[{"type":"reasoning.summary","summary":"\"","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" that","reasoning_details":[{"type":"reasoning.summary","summary":" that","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" takes","reasoning_details":[{"type":"reasoning.summary","summary":" takes","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" a","reasoning_details":[{"type":"reasoning.summary","summary":" a","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" location","reasoning_details":[{"type":"reasoning.summary","summary":" location","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":".\n","reasoning_details":[{"type":"reasoning.summary","summary":".\n","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.encrypted","data":"vLM0Gf3xNi4W6z3m+SXQdwgRJ5j1WF/oVLuLzylmOHXOHDXsyV7YJK3VSndsr0CUMW/hOUz+Mmtu3NJYb1dMJfPmshsUh5JLbLAh1gn8lrgPFI8j5aS7sT8+jTTZnbYafPxuA3pAEDdU4DmtmiWolUDsnjoYj3VjF8Ct/ZvIBkh32jeTbLGYI8zF/1nYUJiGZO44QbSQMhf+xunO3kOdXAvomwFRD0TEwiCaXyuckFrZBU8lUeurYuzzVS3v2h2MoRwuuzOrcC+4EyyDoYwIoAy2W28BFfFWV+4gpfW0qLXZbL9Qd5qeOLqMPRdvO4ebaJrpXk/mHA2BOjTN6qu6KtzEmqvzZSmXf9oWw0NQojlAhwurnc6Z5ZSvhYgLvbB3NlljJkQ6DpQ9ecjY8nT30t7v0Pz9THdWSei7g+yGFsF44nHIdpo1ctRwIFCTZ33gsq2hVKWxWoyZHRiugNdFvs/gyxb0mciizUwuFeH7DR3RcmmwUVQoKnqETO3hcOJNsgKhZ3HqJUlRyZK9+tyL6d/Fmx5goX8szCimBZloMs1bVqxa5q6Pj0Txnbop45j1tkTfl3/myl1VaRzdSA1GQmZYR/FlmfVKKSIys+U89iY8S2jaPFDCsWfYbpmJep6ycEr7QXpV4qPrzde96umm1HK03stnl9Z2","id":"rs_f6077a98-6c5f-4745-98e5-2241e55c7b91_us-east-1","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"id":"call_57963353","index":0,"type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence, Italy\"}"}}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"tool_calls","native_finish_reason":"completed","logprobs":null}]}
+
+ data: {"id":"gen-1761054593-zsT87Ju3qHM6qnqwwu1k","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054593,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":394,"completion_tokens":135,"total_tokens":529,"cost":0.00021218,"is_byok":false,"prompt_tokens_details":{"cached_tokens":384,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00000968,"upstream_inference_completions_cost":0.0002025},"completion_tokens_details":{"reasoning_tokens":109,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 312.72975ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 972
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"call_57963353","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"unknown","index":0,"text":"The user asked for the weather in Florence, Italy. I have a tool called \"weather\" that takes a location.\n","type":"reasoning.text"}]},{"content":"40 C","tool_call_id":"call_57963353","role":"tool"}],"model":"x-ai/grok-code-fast-1","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"First","reasoning_details":[{"type":"reasoning.summary","summary":"First","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" user","reasoning_details":[{"type":"reasoning.summary","summary":" user","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" asked","reasoning_details":[{"type":"reasoning.summary","summary":" asked","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":":","reasoning_details":[{"type":"reasoning.summary","summary":":","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" \"","reasoning_details":[{"type":"reasoning.summary","summary":" \"","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"What's","reasoning_details":[{"type":"reasoning.summary","summary":"What's","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" weather","reasoning_details":[{"type":"reasoning.summary","summary":" weather","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" in","reasoning_details":[{"type":"reasoning.summary","summary":" in","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Florence","reasoning_details":[{"type":"reasoning.summary","summary":" Florence","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":" Italy","reasoning_details":[{"type":"reasoning.summary","summary":" Italy","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"?\"\n","reasoning_details":[{"type":"reasoning.summary","summary":"?\"\n","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":"\n\n## Investigating weather details \n- The user requested information about the weather in Florence, Italy.","reasoning_details":[{"type":"reasoning.summary","summary":"\n\n## Investigating weather details \n- The user requested information about the weather in Florence, Italy.","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.encrypted","data":"8wgdnDSj2zPZIZurIAkYjGHUndExEDwsxNbnEOlAAvf+T+WGechq1xITxuEysk1EyZXCqTAkQmRX9nWk8fzwu4KpjxJaJx+w4QW5GDGdLyGsHGJhPyDUhvpa5xzUPTa0XwkaIiRwEBOTeDKgnBQY/pNknWeD3e75dRbHwz4ZAyWT1aUh0uv11bdfFHaFr+Ew0djmML0/ZVmE7pNnzJ2EI+Kjdsfnt6DBu3s+PXch1JUushRc7SYK0zTmjI6kk/qxEJah3HdST+DPi6jM2LRGjYwlT5em8dw9Yc6+tHgOz4dvBdz0Q85NBeX5ejhQKF/+vRgSUMWQyPkX4Sv4YrU5NUCowFMP+1k65/2WHICBH0VqLvSgXHRQzd6dIjvArg5c7YpeL8F9CR/N96LaNuHlGOM4p4P+qwoZytD56F8/oo6HRY46Fd6ps13ayQjHi5CvIx67paQLzyLRRbojjeroI6ulOGVI9X/rt84KbPQvy9OBeWMOS8WNH7Wj/gTAUs1lOirSiP5eBrx6ONjxxRuBIrAwO0gd5E2mNKOedFfaw3d9Qfxj1Y3jVLUSabOi9W570oM24xdulFUP6tHvZ8NILru9uslvPTmnAhd2VbI2R1IqZQrasBEK2OGhEwPSzK8dql4YHI8gO6KxWPk1tWlUDJJ2cVVENjxxWhHY8aH7t2qKNqTZDfloxvxX4u/ENQVMId5jLojj2NNcaZJhjTh5sJx9SmTZZ0VA4Ftp0z04o6kZNuBqaoUJfBsVApiF3Wm/VlZccOcP7ojLJIh+4jZRXDrG43yavyik7228jDNl/GEpHTDVwC0KlqGbaNyQBzQD5YhmbbMiweM4i0pzLbErJ+I8OkM2mupBV74gpkmOCi3cs6kRfM/2ptQBCww3Gj+fOcFjmkYsASFUEoIXMnfFAU5dyFRl9AGnKH003mPxDhbH7zrl6jcqqBB/tiSBf9rDX9Jy3xuLUp55+Yj4PaN9CGGfhqseJZOl+GnSXjBwIGyUwpPeXVI0UhAjZoL4t7XA7N/znCT1BaLFu+6hPTUOKrul600bcqyVI9c6pNNW1EmpkI7DY5Sg6/75B3jxeJcQlCr92hu5dV456vHKB5wxv6ThY+eHA/mg+yg9v+gIRkyWPrHrzzrBuKBnfzpWu9vcr5SARMR44u6FOTrEJHRG/PEEnwtqPCYQ4rj6aKdCKVXUOtavYy8I9g2QmuBFP/8seoA","id":"rs_5f9caae1-b0b3-da8f-65b1-96f4da9f96bd_us-east-1","format":"xai-responses-v1","index":0}]},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"The"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" current"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" temperature"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" in"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" Florence"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":","},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" Italy"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" is"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"40"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"°C"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" ("},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"104"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"°F"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"),"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" which"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" is"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" quite"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" hot"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"ā"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"perfect"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" for"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" enjoying"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" some"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" gel"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"ato"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" by"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" the"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" Duomo"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"!"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" If"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" you"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" need"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" a"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" forecast"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" or"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" more"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" details"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":","},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" let"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" me"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":" know"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":"."},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"completed","logprobs":null}]}
+
+ data: {"id":"gen-1761054598-KyDcTvXNnOBxA7koHhEv","provider":"xAI","model":"x-ai/grok-code-fast-1","object":"chat.completion.chunk","created":1761054598,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":432,"completion_tokens":232,"total_tokens":664,"cost":0.00036528,"is_byok":false,"prompt_tokens_details":{"cached_tokens":384,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00001728,"upstream_inference_completions_cost":0.000348},"completion_tokens_details":{"reasoning_tokens":189,"image_tokens":0}}}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 308.0665ms
diff --git a/internal/fantasy/providertests/testdata/TestOpenRouterThinking/grok-code-fast-1/thinking.yaml b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/grok-code-fast-1/thinking.yaml
new file mode 100644
index 000000000..20fabb566
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestOpenRouterThinking/grok-code-fast-1/thinking.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 503
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"x-ai/grok-code-fast-1","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n{\"id\":\"gen-1761054588-hONB7UkTtn3Dfk6ux8Tx\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion\",\"created\":1761054588,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"completed\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":\"The user asked about the weather in Florence, Italy. I need to use the weather tool.\\n\",\"tool_calls\":[{\"id\":\"call_28006909\",\"index\":0,\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\":\\\"Florence, Italy\\\"}\"}}],\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"The user asked about the weather in Florence, Italy. I need to use the weather tool.\\n\",\"format\":\"xai-responses-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"/ChTop77TmqTXj3klZ35dzcHUdOJiT1HyqbNfvhcdv/J9CTdynbZHNsnC0PKYScvNnuPlyl53Md1xfuBSczoPEFjWrxJC8c/8CKKG7MLvX5kqTRaUVneuO6nsKMMkFnTzxsOZZ8oXsjUCqwMu/VuTTS+i1wsAuAdBh1ILyoKUB00fk1qHF7G+EFmu851h0X8cLzcdPo1Mpy1H9han60HCMwp0etZevVOjUFTILUbe1lk37SKvaoT3J8vxTJDry0ZCZG32wDwBqjM7wC8vclM+oZyr2pvgQeQ0EKKmAGlmRsU/bgjCinRSHpohkYC6WaGV/Al606zwXPXgvxdx7LB0vftvNvDVTce+aYf7yGPWf6puxxKtaJZKi7Yp8+koRHVlXXFIcmrV89lo2IAkyKbakV6o56l7rxFL11x6oflq2yMI9VYpiTJ8jLSEzZ6JLhj4UIEz4o13r8rMZ15hUqLX7jg4MUf58+cTjF4918+trtjuJq2gqwtqVMeEUfl\",\"id\":\"rs_2904ed52-6352-e6f9-99e6-9cb0ee4ae8cf_us-east-1\",\"format\":\"xai-responses-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":394,\"completion_tokens\":103,\"total_tokens\":497,\"cost\":0.0001757,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":320,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000212,\"upstream_inference_completions_cost\":0.0001545},\"completion_tokens_details\":{\"reasoning_tokens\":77,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 929.331333ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 896
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"call_28006909","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"unknown","index":0,"text":"The user asked about the weather in Florence, Italy. I need to use the weather tool.\n","type":"reasoning.text"}]},{"content":"40 C","tool_call_id":"call_28006909","role":"tool"}],"model":"x-ai/grok-code-fast-1","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"effort":"medium"},"usage":{"include":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://openrouter.ai/api/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: "\n \n\n \n\n \n\n \n\n \n\n \n{\"id\":\"gen-1761054590-6jqK0pfBCu2FDnT8eYMJ\",\"provider\":\"xAI\",\"model\":\"x-ai/grok-code-fast-1\",\"object\":\"chat.completion\",\"created\":1761054590,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"completed\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The current temperature in Florence, Italy, is 40°C. (Note: This appears to be a temperature reading; full weather details like conditions, humidity, etc., are not provided by the available tool.)\",\"refusal\":null,\"reasoning\":\"The user asked about the weather in Florence, Italy. I used the weather tool and got \\\"40 C\\\". That seems like a temperature reading.\\n\",\"reasoning_details\":[{\"type\":\"reasoning.summary\",\"summary\":\"The user asked about the weather in Florence, Italy. I used the weather tool and got \\\"40 C\\\". That seems like a temperature reading.\\n\",\"format\":\"xai-responses-v1\",\"index\":0},{\"type\":\"reasoning.encrypted\",\"data\":\"fmTdkRw5lFj9LjT4uxrSnq6l/xnCSUyLseuMG7m+Rf76aUcBXnejr+z1ENSBTEgsAm+mfg8dtx5NjMnLKh5rphGSWae8MRVxHdX2Tk/tQWF8WpipQafCpceLmVi7KEm9OP3mw5xHLxPt1sSdXzp8P24JlMM2yzba1aiPjxSFP+yPfy9Zwe6pUQhKrTIkeFEVxrGqfnJ58+bF6l6dSnp8I79vHUwjf8fkN1Uqfyb4bHm0lI3qqPUZNSkeS4NZxKavemmmrzxDNtQZxCWk62D6v77Hr4+zABbJkBbB9iRzjGfMNWB4o6FBgRUirGhhHrvt3r7IdnwRyCz9/4rgEV0kLj1Fa6VTqfKsYTetiufhq25HcH2VCW5xNY87DUz+ZUOEoy2kk8SzHQ411Y/0SK0OKdCiEgN+EUpqT8tIaO/cJeB+AftPGEOUA0lzMH+FClxUg02VOUFptuHLNs4u5N7t3Z+5V1gU+em7MRsaMHoZ6aTKobxSDwHPzCNMzAH4F0uaUpfiCBb5tTPM5w2SABcXcOV2+DnvMF9MqokSMmvrOxZ0f1Kx1Cr546qlf+98m1Tc7kTUOu8h4UcN76E94ywS1rkTyxUkoiy1/B11EzkudZJUvOiE/pUSJZwSGoGv8ZPyXefOtBQ3bK9b1vxBnRA0tw6wG77uR5TDMyR8n816iHI0k7YxQV+1MJualsXMFMAjda2N1gl1/c2cSOjLeLiaKmD8Y3E5CmHSmPl3dIt1ZZulivNIwZhWrFVb1QUZjpZsP4luXZuGa+iTtrtWRZG8AoNAWw9vmwsM8y1VbM39R59++IwRJ+F9M+NAE2B9l9iXmmnDwoegDIkKihHLiwRoV8paRQdixAp0jIAsG/GUWsuNbZ02vkdWgdseGNePib7cf8qrZlbUGUOIAqzoxRa4FWxElf55V5LEnT/yt2+bOSAjlZ6TjNWbvgLV1M/WCbyfs/eirlI5TVvXobCE0ksvYgopGdscyr6V7+Ywjx2EnyR43w\",\"id\":\"rs_ff7bbd1e-238d-a798-ab38-3ecebd8ad160_us-east-1\",\"format\":\"xai-responses-v1\",\"index\":0}]}}],\"usage\":{\"prompt_tokens\":432,\"completion_tokens\":198,\"total_tokens\":630,\"cost\":0.0003258,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":320,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000288,\"upstream_inference_completions_cost\":0.000297},\"completion_tokens_details\":{\"reasoning_tokens\":156,\"image_tokens\":0}}}"
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 416.846166ms
diff --git a/internal/fantasy/providertests/testdata/TestSimple/google-vertex-claude-sonnet.yaml b/internal/fantasy/providertests/testdata/TestSimple/google-vertex-claude-sonnet.yaml
new file mode 100644
index 000000000..2797c38e0
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestSimple/google-vertex-claude-sonnet.yaml
@@ -0,0 +1,3 @@
+---
+version: 2
+interactions: []
diff --git a/internal/fantasy/providertests/testdata/TestSimple/google-vertex-gemini-2.5-flash.yaml b/internal/fantasy/providertests/testdata/TestSimple/google-vertex-gemini-2.5-flash.yaml
new file mode 100644
index 000000000..211a2c94b
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestSimple/google-vertex-gemini-2.5-flash.yaml
@@ -0,0 +1,70 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 180
+ host: us-central1-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Say hi in Portuguese"}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.25.0 gl-go/go1.25.0
+ url: https://us-central1-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-central1/publishers/google/models/gemini-2.5-flash:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "role": "model",
+ "parts": [
+ {
+ "text": "OlĆ”!"
+ }
+ ]
+ },
+ "finishReason": "STOP",
+ "avgLogprobs": -0.57995378971099854
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 9,
+ "candidatesTokenCount": 2,
+ "totalTokenCount": 37,
+ "trafficType": "ON_DEMAND",
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 9
+ }
+ ],
+ "candidatesTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 2
+ }
+ ],
+ "thoughtsTokenCount": 26
+ },
+ "modelVersion": "gemini-2.5-flash",
+ "createTime": "2025-09-24T19:46:03.607780Z",
+ "responseId": "e0rUaKSMJb-gm9IP0PuYmQo"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 1.489268833s
diff --git a/internal/fantasy/providertests/testdata/TestSimple/google-vertex-gemini-2.5-pro.yaml b/internal/fantasy/providertests/testdata/TestSimple/google-vertex-gemini-2.5-pro.yaml
new file mode 100644
index 000000000..48a671285
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestSimple/google-vertex-gemini-2.5-pro.yaml
@@ -0,0 +1,70 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 180
+ host: us-central1-aiplatform.googleapis.com
+ body: |
+ {"contents":[{"parts":[{"text":"Say hi in Portuguese"}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"You are a helpful assistant"}],"role":"user"}}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - google-genai-sdk/1.25.0 gl-go/go1.25.0
+ url: https://us-central1-aiplatform.googleapis.com/v1beta1/projects/fantasy-playground-472418/locations/us-central1/publishers/google/models/gemini-2.5-pro:generateContent
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: |
+ {
+ "candidates": [
+ {
+ "content": {
+ "role": "model",
+ "parts": [
+ {
+ "text": "Of course! The most common ways to say \"hi\" in Portuguese are:\n\n* **OlĆ”** (oh-LAH) - This is the equivalent of \"hello\" and can be used in any situation.\n* **Oi** (oy) - This is more informal, like \"hi,\" and is extremely common, especially in Brazil.\n\nYou can also use a greeting depending on the time of day:\n\n* **Bom dia** (bohm JEE-ah) - Good morning\n* **Boa tarde** (BOH-ah TAR-jee) - Good afternoon\n* **Boa noite** (BOH-ah NOY-tchee) - Good evening / Good night"
+ }
+ ]
+ },
+ "finishReason": "STOP",
+ "avgLogprobs": -0.93591674386638479
+ }
+ ],
+ "usageMetadata": {
+ "promptTokenCount": 9,
+ "candidatesTokenCount": 146,
+ "totalTokenCount": 905,
+ "trafficType": "ON_DEMAND",
+ "promptTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 9
+ }
+ ],
+ "candidatesTokensDetails": [
+ {
+ "modality": "TEXT",
+ "tokenCount": 146
+ }
+ ],
+ "thoughtsTokenCount": 750
+ },
+ "modelVersion": "gemini-2.5-pro",
+ "createTime": "2025-09-24T19:46:04.550048Z",
+ "responseId": "fErUaKDJIaChmecP8LzZwQs"
+ }
+ headers:
+ Content-Type:
+ - application/json; charset=UTF-8
+ status: 200 OK
+ code: 200
+ duration: 8.665756459s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/multi_tool.yaml
new file mode 100644
index 000000000..7ab9ef881
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 830
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF37K2HQCCQMFG024V4NNE3","object":"chat.completion","created":1770033239,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"message":{"role":"assistant","content":null,"tool_calls":[{"id":"toolu_01Pp7heoom1NFVC9pZAq7RVP","type":"function","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"}},{"id":"toolu_01CyT9hTRh1yDg65BtKKoQoJ","type":"function","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"}}],"provider_metadata":{"anthropic":{"usage":{"input_tokens":507,"output_tokens":135,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":335024.437964,"endTime":337607.847298,"statusCode":200,"providerResponseId":"msg_01K9VNT3Y7C6bhS39BSLDfma"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.003546","marketCost":"0.003546","generationId":"gen_01KGF37K2HQCCQMFG024V4NNE3","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":507,"completion_tokens":135,"total_tokens":642,"cost":0.003546,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.003546},"system_fingerprint":"fp_lt5c47efr0","generationId":"gen_01KGF37K2HQCCQMFG024V4NNE3"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.695440458s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1259
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"toolu_01Pp7heoom1NFVC9pZAq7RVP","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"toolu_01CyT9hTRh1yDg65BtKKoQoJ","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"toolu_01Pp7heoom1NFVC9pZAq7RVP","role":"tool"},{"content":"6","tool_call_id":"toolu_01CyT9hTRh1yDg65BtKKoQoJ","role":"tool"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF37NPK9H15VB93JDFXHTFA","object":"chat.completion","created":1770033242,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"message":{"role":"assistant","content":"I''ve performed both operations with the numbers 2 and 3:\n- Addition: 2 + 3 = 5\n- Multiplication: 2 Ć 3 = 6","provider_metadata":{"anthropic":{"usage":{"input_tokens":688,"output_tokens":47,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":4529729.487684,"endTime":4532485.133344,"statusCode":200,"providerResponseId":"msg_01NmyxoER7vKZW5SBBtUa98q"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.002769","marketCost":"0.002769","generationId":"gen_01KGF37NPK9H15VB93JDFXHTFA","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":688,"completion_tokens":47,"total_tokens":735,"cost":0.002769,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002769},"system_fingerprint":"fp_iwzjnx4gms","generationId":"gen_01KGF37NPK9H15VB93JDFXHTFA"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.965395875s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/multi_tool_streaming.yaml
new file mode 100644
index 000000000..ba630b779
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/multi_tool_streaming.yaml
@@ -0,0 +1,113 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 867
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF37RMDX4SKJG4WVQMM9169","object":"chat.completion.chunk","created":1770033244,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_hia2ehn86q"}
+
+ data: {"id":"gen_01KGF37RMDX4SKJG4WVQMM9169","object":"chat.completion.chunk","created":1770033244,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"I"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_hia2ehn86q"}
+
+ data: {"id":"gen_01KGF37RMDX4SKJG4WVQMM9169","object":"chat.completion.chunk","created":1770033244,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"'ll add an"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_hia2ehn86q"}
+
+ data: {"id":"gen_01KGF37RMDX4SKJG4WVQMM9169","object":"chat.completion.chunk","created":1770033244,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"d multiply the"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_hia2ehn86q"}
+
+ data: {"id":"gen_01KGF37RMDX4SKJG4WVQMM9169","object":"chat.completion.chunk","created":1770033244,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" numbers 2 and 3 "},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_hia2ehn86q"}
+
+ data: {"id":"gen_01KGF37RMDX4SKJG4WVQMM9169","object":"chat.completion.chunk","created":1770033244,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"for you."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_hia2ehn86q"}
+
+ data: {"id":"gen_01KGF37RMDX4SKJG4WVQMM9169","object":"chat.completion.chunk","created":1770033244,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"toolu_0135npjMLttuPFBue5jmkrQ7","type":"function","function":{"name":"add","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_hia2ehn86q"}
+
+ data: {"id":"gen_01KGF37RMDX4SKJG4WVQMM9169","object":"chat.completion.chunk","created":1770033244,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"a\": 2"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_hia2ehn86q"}
+
+ data: {"id":"gen_01KGF37RMDX4SKJG4WVQMM9169","object":"chat.completion.chunk","created":1770033244,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":", \""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_hia2ehn86q"}
+
+ data: {"id":"gen_01KGF37RMDX4SKJG4WVQMM9169","object":"chat.completion.chunk","created":1770033244,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"b\": 3}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_hia2ehn86q"}
+
+ data: {"id":"gen_01KGF37RMDX4SKJG4WVQMM9169","object":"chat.completion.chunk","created":1770033244,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"toolu_0158fwcmJxxApeN8LydKZFKq","type":"function","function":{"name":"multiply","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_hia2ehn86q"}
+
+ data: {"id":"gen_01KGF37RMDX4SKJG4WVQMM9169","object":"chat.completion.chunk","created":1770033244,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"a\": 2"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_hia2ehn86q"}
+
+ data: {"id":"gen_01KGF37RMDX4SKJG4WVQMM9169","object":"chat.completion.chunk","created":1770033244,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":", \"b"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_hia2ehn86q"}
+
+ data: {"id":"gen_01KGF37RMDX4SKJG4WVQMM9169","object":"chat.completion.chunk","created":1770033244,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"\": 3}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_hia2ehn86q"}
+
+ data: {"id":"gen_01KGF37RMDX4SKJG4WVQMM9169","object":"chat.completion.chunk","created":1770033244,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"provider_metadata":{"anthropic":{"usage":{"input_tokens":502,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":137,"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":1348791.685811,"endTime":1350481.290097,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":1348791.685811,"endTime":1350481.290097,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.003561","marketCost":"0.003561","generationId":"gen_01KGF37RMDX4SKJG4WVQMM9169","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":502,"completion_tokens":137,"total_tokens":639,"cost":0.003561,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.003561},"system_fingerprint":"fp_hia2ehn86q","generationId":"gen_01KGF37RMDX4SKJG4WVQMM9169"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.838556459s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1365
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"I''ll add and multiply the numbers 2 and 3 for you.","tool_calls":[{"id":"toolu_0135npjMLttuPFBue5jmkrQ7","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"toolu_0158fwcmJxxApeN8LydKZFKq","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"toolu_0135npjMLttuPFBue5jmkrQ7","role":"tool"},{"content":"6","tool_call_id":"toolu_0158fwcmJxxApeN8LydKZFKq","role":"tool"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF37VJZFMN3ZHEKK9EGN5P1","object":"chat.completion.chunk","created":1770033246,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_sdbcn0gb5k"}
+
+ data: {"id":"gen_01KGF37VJZFMN3ZHEKK9EGN5P1","object":"chat.completion.chunk","created":1770033246,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_sdbcn0gb5k"}
+
+ data: {"id":"gen_01KGF37VJZFMN3ZHEKK9EGN5P1","object":"chat.completion.chunk","created":1770033246,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" results"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_sdbcn0gb5k"}
+
+ data: {"id":"gen_01KGF37VJZFMN3ZHEKK9EGN5P1","object":"chat.completion.chunk","created":1770033246,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" are"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_sdbcn0gb5k"}
+
+ data: {"id":"gen_01KGF37VJZFMN3ZHEKK9EGN5P1","object":"chat.completion.chunk","created":1770033246,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":":\n- "},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_sdbcn0gb5k"}
+
+ data: {"id":"gen_01KGF37VJZFMN3ZHEKK9EGN5P1","object":"chat.completion.chunk","created":1770033246,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"2 + 3 = "},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_sdbcn0gb5k"}
+
+ data: {"id":"gen_01KGF37VJZFMN3ZHEKK9EGN5P1","object":"chat.completion.chunk","created":1770033246,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"5\n- 2 Ć "},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_sdbcn0gb5k"}
+
+ data: {"id":"gen_01KGF37VJZFMN3ZHEKK9EGN5P1","object":"chat.completion.chunk","created":1770033246,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"3 = 6"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_sdbcn0gb5k"}
+
+ data: {"id":"gen_01KGF37VJZFMN3ZHEKK9EGN5P1","object":"chat.completion.chunk","created":1770033246,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"provider_metadata":{"anthropic":{"usage":{"input_tokens":700,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":31,"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":7614629.293412,"endTime":7615648.604763,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":7614629.293412,"endTime":7615648.604763,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.002565","marketCost":"0.002565","generationId":"gen_01KGF37VJZFMN3ZHEKK9EGN5P1","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":700,"completion_tokens":31,"total_tokens":731,"cost":0.002565,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002565},"system_fingerprint":"fp_sdbcn0gb5k","generationId":"gen_01KGF37VJZFMN3ZHEKK9EGN5P1"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.108064583s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/simple.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/simple.yaml
new file mode 100644
index 000000000..c62fe28e8
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 175
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF377728Q76J66SN7WNPNNP","object":"chat.completion","created":1770033226,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"message":{"role":"assistant","content":"OlĆ”! \n\nThat''s \"hi\" in Portuguese. You could also say \"Oi!\" which is a bit more casual and friendly.","provider_metadata":{"anthropic":{"usage":{"input_tokens":16,"output_tokens":35,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":1330927.642499,"endTime":1332861.743603,"statusCode":200,"providerResponseId":"msg_01KTuWnKf9GVVspdbvDRUbTo"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.000573","marketCost":"0.000573","generationId":"gen_01KGF377728Q76J66SN7WNPNNP","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":16,"completion_tokens":35,"total_tokens":51,"cost":0.000573,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.000573},"system_fingerprint":"fp_t6mx2uhujo","generationId":"gen_01KGF377728Q76J66SN7WNPNNP"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.374222792s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/simple_streaming.yaml
new file mode 100644
index 000000000..cf48e674d
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/simple_streaming.yaml
@@ -0,0 +1,62 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 229
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF379703450NEHTHYWRXNWC","object":"chat.completion.chunk","created":1770033227,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5a0fyewqxl"}
+
+ data: {"id":"gen_01KGF379703450NEHTHYWRXNWC","object":"chat.completion.chunk","created":1770033227,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"Oi!"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5a0fyewqxl"}
+
+ data: {"id":"gen_01KGF379703450NEHTHYWRXNWC","object":"chat.completion.chunk","created":1770033227,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5a0fyewqxl"}
+
+ data: {"id":"gen_01KGF379703450NEHTHYWRXNWC","object":"chat.completion.chunk","created":1770033227,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"\n\n("},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5a0fyewqxl"}
+
+ data: {"id":"gen_01KGF379703450NEHTHYWRXNWC","object":"chat.completion.chunk","created":1770033227,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"You"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5a0fyewqxl"}
+
+ data: {"id":"gen_01KGF379703450NEHTHYWRXNWC","object":"chat.completion.chunk","created":1770033227,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5a0fyewqxl"}
+
+ data: {"id":"gen_01KGF379703450NEHTHYWRXNWC","object":"chat.completion.chunk","created":1770033227,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" also say \"OlĆ”!\" which"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5a0fyewqxl"}
+
+ data: {"id":"gen_01KGF379703450NEHTHYWRXNWC","object":"chat.completion.chunk","created":1770033227,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5a0fyewqxl"}
+
+ data: {"id":"gen_01KGF379703450NEHTHYWRXNWC","object":"chat.completion.chunk","created":1770033227,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" another"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5a0fyewqxl"}
+
+ data: {"id":"gen_01KGF379703450NEHTHYWRXNWC","object":"chat.completion.chunk","created":1770033227,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" common way"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5a0fyewqxl"}
+
+ data: {"id":"gen_01KGF379703450NEHTHYWRXNWC","object":"chat.completion.chunk","created":1770033227,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" to say hi"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5a0fyewqxl"}
+
+ data: {"id":"gen_01KGF379703450NEHTHYWRXNWC","object":"chat.completion.chunk","created":1770033227,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5a0fyewqxl"}
+
+ data: {"id":"gen_01KGF379703450NEHTHYWRXNWC","object":"chat.completion.chunk","created":1770033227,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" Portuguese)"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5a0fyewqxl"}
+
+ data: {"id":"gen_01KGF379703450NEHTHYWRXNWC","object":"chat.completion.chunk","created":1770033227,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"provider_metadata":{"anthropic":{"usage":{"input_tokens":16,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":30,"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":1333898.356903,"endTime":1334761.868909,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":1333898.356903,"endTime":1334761.868909,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.000498","marketCost":"0.000498","generationId":"gen_01KGF379703450NEHTHYWRXNWC","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":16,"completion_tokens":30,"total_tokens":46,"cost":0.000498,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.000498},"system_fingerprint":"fp_5a0fyewqxl","generationId":"gen_01KGF379703450NEHTHYWRXNWC"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 993.576166ms
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/tool.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/tool.yaml
new file mode 100644
index 000000000..ca3bb5c2b
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 467
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF37B48YTSG8HPMC0Z9AVAR","object":"chat.completion","created":1770033230,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"message":{"role":"assistant","content":null,"tool_calls":[{"id":"toolu_01NSrymFZiohT2iy9U5LE9rA","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence,Italy\"}"}}],"provider_metadata":{"anthropic":{"usage":{"input_tokens":394,"output_tokens":67,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":2429109.035804,"endTime":2430987.56251,"statusCode":200,"providerResponseId":"msg_01Ak5uPKnJHaza1hFgS4fMoY"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.002187","marketCost":"0.002187","generationId":"gen_01KGF37B48YTSG8HPMC0Z9AVAR","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":394,"completion_tokens":67,"total_tokens":461,"cost":0.002187,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002187},"system_fingerprint":"fp_u1vgvb877f","generationId":"gen_01KGF37B48YTSG8HPMC0Z9AVAR"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.999195125s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 720
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"toolu_01NSrymFZiohT2iy9U5LE9rA","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"toolu_01NSrymFZiohT2iy9U5LE9rA","role":"tool"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF37D4BQSXP782PJN0Q3KYT","object":"chat.completion","created":1770033233,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"message":{"role":"assistant","content":"The current weather in Florence, Italy is 40°C (104°F). That''s quite hot! It''s a very warm day there.","provider_metadata":{"anthropic":{"usage":{"input_tokens":463,"output_tokens":33,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":410587.245308,"endTime":412600.850201,"statusCode":200,"providerResponseId":"msg_01ReE5KwsYimH5AMRwEuLit9"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.001884","marketCost":"0.001884","generationId":"gen_01KGF37D4BQSXP782PJN0Q3KYT","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":463,"completion_tokens":33,"total_tokens":496,"cost":0.001884,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.001884},"system_fingerprint":"fp_dwzayvqyi3","generationId":"gen_01KGF37D4BQSXP782PJN0Q3KYT"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.1313565s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/tool_streaming.yaml
new file mode 100644
index 000000000..0039e197a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/claude-sonnet-4/tool_streaming.yaml
@@ -0,0 +1,121 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 521
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF37F6TEH1JWRE2BABW1XV7","object":"chat.completion.chunk","created":1770033234,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_22ov8ctw6a"}
+
+ data: {"id":"gen_01KGF37F6TEH1JWRE2BABW1XV7","object":"chat.completion.chunk","created":1770033234,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"I'll get the weather information for Florence"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_22ov8ctw6a"}
+
+ data: {"id":"gen_01KGF37F6TEH1JWRE2BABW1XV7","object":"chat.completion.chunk","created":1770033234,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":", Italy for you."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_22ov8ctw6a"}
+
+ data: {"id":"gen_01KGF37F6TEH1JWRE2BABW1XV7","object":"chat.completion.chunk","created":1770033234,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"toolu_01P61EhnucuCA3gRE8rXpYrt","type":"function","function":{"name":"weather","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_22ov8ctw6a"}
+
+ data: {"id":"gen_01KGF37F6TEH1JWRE2BABW1XV7","object":"chat.completion.chunk","created":1770033234,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"location\""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_22ov8ctw6a"}
+
+ data: {"id":"gen_01KGF37F6TEH1JWRE2BABW1XV7","object":"chat.completion.chunk","created":1770033234,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":": \""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_22ov8ctw6a"}
+
+ data: {"id":"gen_01KGF37F6TEH1JWRE2BABW1XV7","object":"chat.completion.chunk","created":1770033234,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Florence,"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_22ov8ctw6a"}
+
+ data: {"id":"gen_01KGF37F6TEH1JWRE2BABW1XV7","object":"chat.completion.chunk","created":1770033234,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" Ita"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_22ov8ctw6a"}
+
+ data: {"id":"gen_01KGF37F6TEH1JWRE2BABW1XV7","object":"chat.completion.chunk","created":1770033234,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"ly\"}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_22ov8ctw6a"}
+
+ data: {"id":"gen_01KGF37F6TEH1JWRE2BABW1XV7","object":"chat.completion.chunk","created":1770033234,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"provider_metadata":{"anthropic":{"usage":{"input_tokens":394,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":67,"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":1339997.935348,"endTime":1341183.011845,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":1339997.935348,"endTime":1341183.011845,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.002187","marketCost":"0.002187","generationId":"gen_01KGF37F6TEH1JWRE2BABW1XV7","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":394,"completion_tokens":67,"total_tokens":461,"cost":0.002187,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002187},"system_fingerprint":"fp_22ov8ctw6a","generationId":"gen_01KGF37F6TEH1JWRE2BABW1XV7"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.273492958s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 850
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"I''ll get the weather information for Florence, Italy for you.","tool_calls":[{"id":"toolu_01P61EhnucuCA3gRE8rXpYrt","function":{"arguments":"{\"location\": \"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"toolu_01P61EhnucuCA3gRE8rXpYrt","role":"tool"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"The current"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" weather in Florence, Italy shows"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" temperature of 40°C (104"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"°F)."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" That"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"'s quite hot"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"!"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" It woul"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"d be a good idea to stay"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" hydrated and seek"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" shade or"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" air conditioning if you're planning"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" to be"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" out"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"doors."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_xnw4h12lhy"}
+
+ data: {"id":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","object":"chat.completion.chunk","created":1770033235,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"provider_metadata":{"anthropic":{"usage":{"input_tokens":476,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":53,"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":3034449.959696,"endTime":3035377.30027,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":3034449.959696,"endTime":3035377.30027,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.002223","marketCost":"0.002223","generationId":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":476,"completion_tokens":53,"total_tokens":529,"cost":0.002223,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002223},"system_fingerprint":"fp_xnw4h12lhy","generationId":"gen_01KGF37H1H6MYNJHYZ2N1SWF5H"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.122953792s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/multi_tool.yaml
new file mode 100644
index 000000000..5f1fc92ac
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 828
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF381BH2CF0J56H612T8RC3","object":"chat.completion","created":1770033252,"model":"google/gemini-2.5-flash","choices":[{"index":0,"message":{"role":"assistant","content":null,"tool_calls":[{"id":"s3q46gVXfhyIqY2s","type":"function","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"}},{"id":"vomF7JlLjIRlW7U8","type":"function","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"}}],"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":111,"promptTokenCount":61,"candidatesTokenCount":10,"totalTokenCount":182,"trafficType":"ON_DEMAND"}},"gateway":{"routing":{"originalModelId":"google/gemini-2.5-flash","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-2.5-flash","internalResolvedModelId":"vertex:gemini-2.5-flash","fallbacksAvailable":["google","deepinfra"],"internalReasoning":"Selected vertex as preferred provider for gemini-2.5-flash. 2 fallback(s) available: google, deepinfra","planningReasoning":"System credentials planned for: vertex, google, deepinfra. Total execution order: vertex(system) ā google(system) ā deepinfra(system)","canonicalSlug":"google/gemini-2.5-flash","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":true,"startTime":4669622.140163,"endTime":4670671.510973,"statusCode":200,"providerResponseId":"Y5CAadiYMJCgmPUPj9uV-AI"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-2.5-flash","canonicalSlug":"google/gemini-2.5-flash","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.0003208","marketCost":"0.0003208","generationId":"gen_01KGF381BH2CF0J56H612T8RC3","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":61,"completion_tokens":10,"total_tokens":71,"cost":0.0003208,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":111,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.0003208},"system_fingerprint":"fp_q0dgwe4fbo","generationId":"gen_01KGF381BH2CF0J56H612T8RC3"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.184203208s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1201
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"s3q46gVXfhyIqY2s","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"vomF7JlLjIRlW7U8","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"s3q46gVXfhyIqY2s","role":"tool"},{"content":"6","tool_call_id":"vomF7JlLjIRlW7U8","role":"tool"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF382G93A1FEHZRVZDSTMQE","object":"chat.completion","created":1770033253,"model":"google/gemini-2.5-flash","choices":[{"index":0,"message":{"role":"assistant","content":"The sum of 2 and 3 is 5, and the product of 2 and 3 is 6.","provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"promptTokenCount":197,"candidatesTokenCount":25,"totalTokenCount":222}},"gateway":{"routing":{"originalModelId":"google/gemini-2.5-flash","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-2.5-flash","internalResolvedModelId":"vertex:gemini-2.5-flash","fallbacksAvailable":["google","deepinfra"],"internalReasoning":"Selected vertex as preferred provider for gemini-2.5-flash. 2 fallback(s) available: google, deepinfra","planningReasoning":"System credentials planned for: vertex, google, deepinfra. Total execution order: vertex(system) ā google(system) ā deepinfra(system)","canonicalSlug":"google/gemini-2.5-flash","finalProvider":"google","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":false,"error":"Please ensure that the number of function response parts is equal to the number of function call parts of the function call turn.","startTime":1956234.837355,"endTime":1956397.272511,"statusCode":400},{"provider":"google","internalModelId":"google:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":true,"startTime":1956497.822129,"endTime":1956985.150646,"statusCode":200,"providerResponseId":"ZZCAady9I-KF7M8PkM3b4AE"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-2.5-flash","canonicalSlug":"google/gemini-2.5-flash","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.0001216","marketCost":"0.0001216","generationId":"gen_01KGF382G93A1FEHZRVZDSTMQE","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":197,"completion_tokens":25,"total_tokens":222,"cost":0.0001216,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.0001216},"system_fingerprint":"fp_sxou9xxzzl","generationId":"gen_01KGF382G93A1FEHZRVZDSTMQE"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 921.5745ms
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/multi_tool_streaming.yaml
new file mode 100644
index 000000000..25610637b
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/multi_tool_streaming.yaml
@@ -0,0 +1,87 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 865
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF383DF2E9FSJX95AA3ZED7","object":"chat.completion.chunk","created":1770033254,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_nkvitg7moc"}
+
+ data: {"id":"gen_01KGF383DF2E9FSJX95AA3ZED7","object":"chat.completion.chunk","created":1770033254,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"S66o9rnUIliVpcHx","type":"function","function":{"name":"add","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_nkvitg7moc"}
+
+ data: {"id":"gen_01KGF383DF2E9FSJX95AA3ZED7","object":"chat.completion.chunk","created":1770033254,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"b\":3,\"a\":2}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_nkvitg7moc"}
+
+ data: {"id":"gen_01KGF383DF2E9FSJX95AA3ZED7","object":"chat.completion.chunk","created":1770033254,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"6e0NXuEtzAHkTRep","type":"function","function":{"name":"multiply","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_nkvitg7moc"}
+
+ data: {"id":"gen_01KGF383DF2E9FSJX95AA3ZED7","object":"chat.completion.chunk","created":1770033254,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"a\":2,\"b\":3}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_nkvitg7moc"}
+
+ data: {"id":"gen_01KGF383DF2E9FSJX95AA3ZED7","object":"chat.completion.chunk","created":1770033254,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":37,"promptTokenCount":57,"candidatesTokenCount":10,"totalTokenCount":104,"trafficType":"ON_DEMAND"}},"gateway":{"routing":{"originalModelId":"google/gemini-2.5-flash","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-2.5-flash","internalResolvedModelId":"vertex:gemini-2.5-flash","fallbacksAvailable":["google","deepinfra"],"internalReasoning":"Selected vertex as preferred provider for gemini-2.5-flash. 2 fallback(s) available: google, deepinfra","planningReasoning":"System credentials planned for: vertex, google, deepinfra. Total execution order: vertex(system) ā google(system) ā deepinfra(system)","canonicalSlug":"google/gemini-2.5-flash","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":true,"startTime":3167743.289212,"endTime":3168716.703261,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-2.5-flash","canonicalSlug":"google/gemini-2.5-flash","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"vertex","internalModelId":"vertex:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":true,"startTime":3167743.289212,"endTime":3168716.703261,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.0001346","marketCost":"0.0001346","generationId":"gen_01KGF383DF2E9FSJX95AA3ZED7","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":57,"completion_tokens":10,"total_tokens":67,"cost":0.0001346,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":37,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.0001346},"system_fingerprint":"fp_nkvitg7moc","generationId":"gen_01KGF383DF2E9FSJX95AA3ZED7"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.071326459s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1238
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"S66o9rnUIliVpcHx","function":{"arguments":"{\"b\":3,\"a\":2}","name":"add"},"type":"function"},{"id":"6e0NXuEtzAHkTRep","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"S66o9rnUIliVpcHx","role":"tool"},{"content":"6","tool_call_id":"6e0NXuEtzAHkTRep","role":"tool"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF384F3XAWSR4PC2A0QPAGW","object":"chat.completion.chunk","created":1770033255,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_r6gptvhx1g"}
+
+ data: {"id":"gen_01KGF384F3XAWSR4PC2A0QPAGW","object":"chat.completion.chunk","created":1770033255,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"content":"The sum of"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_r6gptvhx1g"}
+
+ data: {"id":"gen_01KGF384F3XAWSR4PC2A0QPAGW","object":"chat.completion.chunk","created":1770033255,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"content":" 2 and 3 is 5, and the product of 2 and"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_r6gptvhx1g"}
+
+ data: {"id":"gen_01KGF384F3XAWSR4PC2A0QPAGW","object":"chat.completion.chunk","created":1770033255,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"content":" 3 is 6."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_r6gptvhx1g"}
+
+ data: {"id":"gen_01KGF384F3XAWSR4PC2A0QPAGW","object":"chat.completion.chunk","created":1770033255,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"promptTokenCount":193,"candidatesTokenCount":23,"totalTokenCount":216}},"gateway":{"routing":{"originalModelId":"google/gemini-2.5-flash","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-2.5-flash","internalResolvedModelId":"vertex:gemini-2.5-flash","fallbacksAvailable":["google","deepinfra"],"internalReasoning":"Selected vertex as preferred provider for gemini-2.5-flash. 2 fallback(s) available: google, deepinfra","planningReasoning":"System credentials planned for: vertex, google, deepinfra. Total execution order: vertex(system) ā google(system) ā deepinfra(system)","canonicalSlug":"google/gemini-2.5-flash","finalProvider":"google","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":false,"error":"Please ensure that the number of function response parts is equal to the number of function call parts of the function call turn.","startTime":3168815.590185,"endTime":3168973.53366,"statusCode":400},{"provider":"google","internalModelId":"google:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":true,"startTime":3169095.201105,"endTime":3169473.585021,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-2.5-flash","canonicalSlug":"google/gemini-2.5-flash","success":true,"providerAttemptCount":2,"providerAttempts":[{"provider":"vertex","internalModelId":"vertex:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":false,"error":"Please ensure that the number of function response parts is equal to the number of function call parts of the function call turn.","startTime":3168815.590185,"endTime":3168973.53366,"statusCode":400},{"provider":"google","internalModelId":"google:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":true,"startTime":3169095.201105,"endTime":3169473.585021,"statusCode":200}]}],"totalProviderAttemptCount":2},"cost":"0.0001154","marketCost":"0.0001154","generationId":"gen_01KGF384F3XAWSR4PC2A0QPAGW","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":193,"completion_tokens":23,"total_tokens":216,"cost":0.0001154,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.0001154},"system_fingerprint":"fp_r6gptvhx1g","generationId":"gen_01KGF384F3XAWSR4PC2A0QPAGW"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 752.724625ms
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/simple.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/simple.yaml
new file mode 100644
index 000000000..9676008c6
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 173
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"google/gemini-2.5-flash","max_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF37X8BY3AB4X8CN72NQHAV","object":"chat.completion","created":1770033248,"model":"google/gemini-2.5-flash","choices":[{"index":0,"message":{"role":"assistant","content":"OlĆ”!","provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":23,"promptTokenCount":9,"candidatesTokenCount":2,"totalTokenCount":34,"trafficType":"ON_DEMAND"}},"gateway":{"routing":{"originalModelId":"google/gemini-2.5-flash","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-2.5-flash","internalResolvedModelId":"vertex:gemini-2.5-flash","fallbacksAvailable":["google","deepinfra"],"internalReasoning":"Selected vertex as preferred provider for gemini-2.5-flash. 2 fallback(s) available: google, deepinfra","planningReasoning":"System credentials planned for: vertex, google, deepinfra. Total execution order: vertex(system) ā google(system) ā deepinfra(system)","canonicalSlug":"google/gemini-2.5-flash","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":true,"startTime":427093.03273,"endTime":427617.793917,"statusCode":200,"providerResponseId":"X5CAaaH-Ipyy2fMP5ezVKA"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-2.5-flash","canonicalSlug":"google/gemini-2.5-flash","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.0000652","marketCost":"0.0000652","generationId":"gen_01KGF37X8BY3AB4X8CN72NQHAV","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":9,"completion_tokens":2,"total_tokens":11,"cost":0.0000652,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":23,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.0000652},"system_fingerprint":"fp_oj9j2v6wic","generationId":"gen_01KGF37X8BY3AB4X8CN72NQHAV"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 605.216666ms
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/simple_streaming.yaml
new file mode 100644
index 000000000..70274c47b
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/simple_streaming.yaml
@@ -0,0 +1,40 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 227
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF37XVPQFTEF88B3MN5VGHK","object":"chat.completion.chunk","created":1770033248,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_1hjld5wcik"}
+
+ data: {"id":"gen_01KGF37XVPQFTEF88B3MN5VGHK","object":"chat.completion.chunk","created":1770033248,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"content":"OlĆ”!"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_1hjld5wcik"}
+
+ data: {"id":"gen_01KGF37XVPQFTEF88B3MN5VGHK","object":"chat.completion.chunk","created":1770033248,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":25,"promptTokenCount":9,"candidatesTokenCount":2,"totalTokenCount":36,"trafficType":"ON_DEMAND"}},"gateway":{"routing":{"originalModelId":"google/gemini-2.5-flash","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-2.5-flash","internalResolvedModelId":"vertex:gemini-2.5-flash","fallbacksAvailable":["google","deepinfra"],"internalReasoning":"Selected vertex as preferred provider for gemini-2.5-flash. 2 fallback(s) available: google, deepinfra","planningReasoning":"System credentials planned for: vertex, google, deepinfra. Total execution order: vertex(system) ā google(system) ā deepinfra(system)","canonicalSlug":"google/gemini-2.5-flash","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":true,"startTime":7617027.32849,"endTime":7617674.256609,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-2.5-flash","canonicalSlug":"google/gemini-2.5-flash","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"vertex","internalModelId":"vertex:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":true,"startTime":7617027.32849,"endTime":7617674.256609,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.0000702","marketCost":"0.0000702","generationId":"gen_01KGF37XVPQFTEF88B3MN5VGHK","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":9,"completion_tokens":2,"total_tokens":11,"cost":0.0000702,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":25,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.0000702},"system_fingerprint":"fp_1hjld5wcik","generationId":"gen_01KGF37XVPQFTEF88B3MN5VGHK"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 875.25225ms
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/tool.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/tool.yaml
new file mode 100644
index 000000000..0c738571b
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 465
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF37YQYT0615AXEWGQMX7A4","object":"chat.completion","created":1770033249,"model":"google/gemini-2.5-flash","choices":[{"index":0,"message":{"role":"assistant","content":null,"tool_calls":[{"id":"2UEinTAmGM13bjwN","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence,Italy\"}"}}],"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":57,"promptTokenCount":28,"candidatesTokenCount":5,"totalTokenCount":90,"trafficType":"ON_DEMAND"}},"gateway":{"routing":{"originalModelId":"google/gemini-2.5-flash","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-2.5-flash","internalResolvedModelId":"vertex:gemini-2.5-flash","fallbacksAvailable":["google","deepinfra"],"internalReasoning":"Selected vertex as preferred provider for gemini-2.5-flash. 2 fallback(s) available: google, deepinfra","planningReasoning":"System credentials planned for: vertex, google, deepinfra. Total execution order: vertex(system) ā google(system) ā deepinfra(system)","canonicalSlug":"google/gemini-2.5-flash","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":true,"startTime":1355937.787241,"endTime":1356631.240553,"statusCode":200,"providerResponseId":"YZCAafTaCP-xhcIP6Zz3mAQ"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-2.5-flash","canonicalSlug":"google/gemini-2.5-flash","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.0001634","marketCost":"0.0001634","generationId":"gen_01KGF37YQYT0615AXEWGQMX7A4","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":28,"completion_tokens":5,"total_tokens":33,"cost":0.0001634,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":57,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.0001634},"system_fingerprint":"fp_q7zc9ylbsc","generationId":"gen_01KGF37YQYT0615AXEWGQMX7A4"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 851.617709ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 690
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"2UEinTAmGM13bjwN","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"2UEinTAmGM13bjwN","role":"tool"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF37ZH945B4T7Q2YDF1YW7K","object":"chat.completion","created":1770033250,"model":"google/gemini-2.5-flash","choices":[{"index":0,"message":{"role":"assistant","content":"The weather in Florence, Italy is 40 C.","provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"promptTokenCount":40,"candidatesTokenCount":12,"totalTokenCount":52,"trafficType":"ON_DEMAND"}},"gateway":{"routing":{"originalModelId":"google/gemini-2.5-flash","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-2.5-flash","internalResolvedModelId":"vertex:gemini-2.5-flash","fallbacksAvailable":["google","deepinfra"],"internalReasoning":"Selected vertex as preferred provider for gemini-2.5-flash. 2 fallback(s) available: google, deepinfra","planningReasoning":"System credentials planned for: vertex, google, deepinfra. Total execution order: vertex(system) ā google(system) ā deepinfra(system)","canonicalSlug":"google/gemini-2.5-flash","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":true,"startTime":347802.523594,"endTime":348287.615775,"statusCode":200,"providerResponseId":"YZCAaYSqO9X8tfAPg7j5QA"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-2.5-flash","canonicalSlug":"google/gemini-2.5-flash","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.000042","marketCost":"0.000042","generationId":"gen_01KGF37ZH945B4T7Q2YDF1YW7K","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":40,"completion_tokens":12,"total_tokens":52,"cost":0.000042,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.000042},"system_fingerprint":"fp_oqc02i8x0x","generationId":"gen_01KGF37ZH945B4T7Q2YDF1YW7K"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 587.012542ms
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/tool_streaming.yaml
new file mode 100644
index 000000000..d5d4aca62
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-2.5-flash/tool_streaming.yaml
@@ -0,0 +1,81 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 519
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF3803YBNDA2M8B7319DJ82","object":"chat.completion.chunk","created":1770033251,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_7in70gabwf"}
+
+ data: {"id":"gen_01KGF3803YBNDA2M8B7319DJ82","object":"chat.completion.chunk","created":1770033251,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"g8BRNPzm2XAHjElR","type":"function","function":{"name":"weather","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_7in70gabwf"}
+
+ data: {"id":"gen_01KGF3803YBNDA2M8B7319DJ82","object":"chat.completion.chunk","created":1770033251,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"location\":\"Florence,Italy\"}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_7in70gabwf"}
+
+ data: {"id":"gen_01KGF3803YBNDA2M8B7319DJ82","object":"chat.completion.chunk","created":1770033251,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":51,"promptTokenCount":28,"candidatesTokenCount":5,"totalTokenCount":84,"trafficType":"ON_DEMAND"}},"gateway":{"routing":{"originalModelId":"google/gemini-2.5-flash","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-2.5-flash","internalResolvedModelId":"vertex:gemini-2.5-flash","fallbacksAvailable":["google","deepinfra"],"internalReasoning":"Selected vertex as preferred provider for gemini-2.5-flash. 2 fallback(s) available: google, deepinfra","planningReasoning":"System credentials planned for: vertex, google, deepinfra. Total execution order: vertex(system) ā google(system) ā deepinfra(system)","canonicalSlug":"google/gemini-2.5-flash","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":true,"startTime":430027.607924,"endTime":430701.108841,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-2.5-flash","canonicalSlug":"google/gemini-2.5-flash","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"vertex","internalModelId":"vertex:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":true,"startTime":430027.607924,"endTime":430701.108841,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.0001484","marketCost":"0.0001484","generationId":"gen_01KGF3803YBNDA2M8B7319DJ82","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":28,"completion_tokens":5,"total_tokens":33,"cost":0.0001484,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":51,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.0001484},"system_fingerprint":"fp_7in70gabwf","generationId":"gen_01KGF3803YBNDA2M8B7319DJ82"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 758.2815ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 744
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"g8BRNPzm2XAHjElR","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"g8BRNPzm2XAHjElR","role":"tool"}],"model":"google/gemini-2.5-flash","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF380V9QM93HK4DBFD3050C","object":"chat.completion.chunk","created":1770033251,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_edgl953q80"}
+
+ data: {"id":"gen_01KGF380V9QM93HK4DBFD3050C","object":"chat.completion.chunk","created":1770033251,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_edgl953q80"}
+
+ data: {"id":"gen_01KGF380V9QM93HK4DBFD3050C","object":"chat.completion.chunk","created":1770033251,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"content":" weather in Florence, Italy is 40 C."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_edgl953q80"}
+
+ data: {"id":"gen_01KGF380V9QM93HK4DBFD3050C","object":"chat.completion.chunk","created":1770033251,"model":"google/gemini-2.5-flash","choices":[{"index":0,"delta":{"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"promptTokenCount":40,"candidatesTokenCount":12,"totalTokenCount":52,"trafficType":"ON_DEMAND"}},"gateway":{"routing":{"originalModelId":"google/gemini-2.5-flash","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-2.5-flash","internalResolvedModelId":"vertex:gemini-2.5-flash","fallbacksAvailable":["google","deepinfra"],"internalReasoning":"Selected vertex as preferred provider for gemini-2.5-flash. 2 fallback(s) available: google, deepinfra","planningReasoning":"System credentials planned for: vertex, google, deepinfra. Total execution order: vertex(system) ā google(system) ā deepinfra(system)","canonicalSlug":"google/gemini-2.5-flash","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":true,"startTime":4541137.912067,"endTime":4541464.788969,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-2.5-flash","canonicalSlug":"google/gemini-2.5-flash","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"vertex","internalModelId":"vertex:gemini-2.5-flash","providerApiModelId":"gemini-2.5-flash","credentialType":"system","success":true,"startTime":4541137.912067,"endTime":4541464.788969,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.000042","marketCost":"0.000042","generationId":"gen_01KGF380V9QM93HK4DBFD3050C","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":40,"completion_tokens":12,"total_tokens":52,"cost":0.000042,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.000042},"system_fingerprint":"fp_edgl953q80","generationId":"gen_01KGF380V9QM93HK4DBFD3050C"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 425.562958ms
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/multi_tool.yaml
new file mode 100644
index 000000000..0e3d6bb09
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 832
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF39J2GMGMAPH0F955QXJN5","object":"chat.completion","created":1770033304,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"message":{"role":"assistant","content":null,"tool_calls":[{"id":"yr8vjBiBxciYk81p","type":"function","function":{"name":"add","arguments":"{\"b\":3,\"a\":2}"}},{"id":"AmDRMtn5jFH1FM4J","type":"function","function":{"name":"multiply","arguments":"{\"b\":3,\"a\":2}"}}],"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":119,"promptTokenCount":61,"candidatesTokenCount":18,"totalTokenCount":198,"trafficType":"PROVISIONED_THROUGHPUT"}},"gateway":{"routing":{"originalModelId":"google/gemini-3-pro-preview","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-3-pro-preview","internalResolvedModelId":"vertex:gemini-3-pro-preview","fallbacksAvailable":["google"],"internalReasoning":"Selected vertex as preferred provider for gemini-3-pro-preview. 1 fallback(s) available: google","planningReasoning":"System credentials planned for: vertex, google. Total execution order: vertex(system) ā google(system)","canonicalSlug":"google/gemini-3-pro-preview","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":7050722.565232,"endTime":7053930.218976,"statusCode":200,"providerResponseId":"lZCAaejDKf6BmLAPjqmi-Qo"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-3-pro-preview","canonicalSlug":"google/gemini-3-pro-preview","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.001766","marketCost":"0.001766","generationId":"gen_01KGF39J2GMGMAPH0F955QXJN5","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":61,"completion_tokens":18,"total_tokens":79,"cost":0.001766,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":119,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.001766},"system_fingerprint":"fp_sbwyjrbwm9","generationId":"gen_01KGF39J2GMGMAPH0F955QXJN5"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.301019917s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1205
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"yr8vjBiBxciYk81p","function":{"arguments":"{\"b\":3,\"a\":2}","name":"add"},"type":"function"},{"id":"AmDRMtn5jFH1FM4J","function":{"arguments":"{\"b\":3,\"a\":2}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"yr8vjBiBxciYk81p","role":"tool"},{"content":"6","tool_call_id":"AmDRMtn5jFH1FM4J","role":"tool"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF39N3ZQQNAHVCNDKGKFDXH","object":"chat.completion","created":1770033309,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"message":{"role":"assistant","content":"The sum of 2 and 3 is 5, and the product of 2 and 3 is 6.","reasoning_details":[{"type":"reasoning.encrypted","data":"EowECokEAXLI2nxcmOHKFmCie8wZQj4/lvp5r14Pp4tqdLOscZ0XBOKdSP60HUPURffivhxpaKDjwvyYIf43reXC7PyAzrNjw/g82cNAjfDK7wpy9ytBDKW8Jmn0KghvDqliK1EHUa5r5phWGwyclW3coT/6X1mtcQd89uAjf3qg3HyAvSNRrpjY+5E8i1CWh9Klnz+4AJ6cAHyahhkqS6Kc/0fZWFwggkOYPetH/bLrdipfcjBOIyRsWg8YeR9iRiv2cBbHruJeops0JKxCVhr750bJiYYehM3eOgvfD6rXA9TJnv6+sjoGXK/kWkrFW84i7lJvbDZaonJwVbDe3B1qpm+cmiGRHDHBQDam9dfLnRoeuk8lvEHtJctSIGRKSG+qavsxhHsr+IyWolld74TkIc7/dFHqJvCUkp8UtIg7KFMIHsQmi0FGn2IpUK/pW47Q8wT9eUdbxr8FFkmcsTMziI1QexEK1bosMZYDYc6AnQ3HXQzGuCq/Alx8jaku4xeyl1xplmMCKPui0AvK05/uKD08xSmWouSi3iMsIxj/1QRvrejj22oT7DiHZuL/DKp8tnCR2f3M/U8OmxMr665dpyWMfrBLAFL0KL7AQGoRqpxoLEbTmISk5wDaxYdXqnLhgPw9qF4TCRYnUQNfSbzIfKmCk/ekKwX0NBROCJu5yhVEBsMEevDTC/sg8q0=","format":"google-gemini-v1","index":0}],"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":119,"promptTokenCount":223,"candidatesTokenCount":25,"totalTokenCount":367}},"gateway":{"routing":{"originalModelId":"google/gemini-3-pro-preview","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-3-pro-preview","internalResolvedModelId":"vertex:gemini-3-pro-preview","fallbacksAvailable":["google"],"internalReasoning":"Selected vertex as preferred provider for gemini-3-pro-preview. 1 fallback(s) available: google","planningReasoning":"System credentials planned for: vertex, google. Total execution order: vertex(system) ā google(system)","canonicalSlug":"google/gemini-3-pro-preview","finalProvider":"google","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":false,"error":"Please ensure that the number of function response parts is equal to the number of function call parts of the function call turn.","startTime":7674067.523962,"endTime":7674739.16189,"statusCode":400},{"provider":"google","internalModelId":"google:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":7674863.56271,"endTime":7678582.662173,"statusCode":200,"providerResponseId":"nZCAaaflFeKF7M8Pis3b4AE"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-3-pro-preview","canonicalSlug":"google/gemini-3-pro-preview","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.002174","marketCost":"0.002174","generationId":"gen_01KGF39N3ZQQNAHVCNDKGKFDXH","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":223,"completion_tokens":25,"total_tokens":248,"cost":0.002174,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":119,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002174},"system_fingerprint":"fp_q0jgoj8amw","generationId":"gen_01KGF39N3ZQQNAHVCNDKGKFDXH"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 4.618416166s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/multi_tool_streaming.yaml
new file mode 100644
index 000000000..20871ca79
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/multi_tool_streaming.yaml
@@ -0,0 +1,85 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 869
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF39SRSQ5CWVF17GR4P29CK","object":"chat.completion.chunk","created":1770033312,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_4r8izhsq38"}
+
+ data: {"id":"gen_01KGF39SRSQ5CWVF17GR4P29CK","object":"chat.completion.chunk","created":1770033312,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"Oxu2MENhE0ZsrlGm","type":"function","function":{"name":"add","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_4r8izhsq38"}
+
+ data: {"id":"gen_01KGF39SRSQ5CWVF17GR4P29CK","object":"chat.completion.chunk","created":1770033312,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"b\":3,\"a\":2}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_4r8izhsq38"}
+
+ data: {"id":"gen_01KGF39SRSQ5CWVF17GR4P29CK","object":"chat.completion.chunk","created":1770033312,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"jHpVWOzg44py3a4h","type":"function","function":{"name":"multiply","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_4r8izhsq38"}
+
+ data: {"id":"gen_01KGF39SRSQ5CWVF17GR4P29CK","object":"chat.completion.chunk","created":1770033312,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"b\":3,\"a\":2}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_4r8izhsq38"}
+
+ data: {"id":"gen_01KGF39SRSQ5CWVF17GR4P29CK","object":"chat.completion.chunk","created":1770033312,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":76,"promptTokenCount":57,"candidatesTokenCount":18,"totalTokenCount":151,"trafficType":"PROVISIONED_THROUGHPUT"}},"gateway":{"routing":{"originalModelId":"google/gemini-3-pro-preview","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-3-pro-preview","internalResolvedModelId":"vertex:gemini-3-pro-preview","fallbacksAvailable":["google"],"internalReasoning":"Selected vertex as preferred provider for gemini-3-pro-preview. 1 fallback(s) available: google","planningReasoning":"System credentials planned for: vertex, google. Total execution order: vertex(system) ā google(system)","canonicalSlug":"google/gemini-3-pro-preview","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":7678877.96491,"endTime":7682011.782537,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-3-pro-preview","canonicalSlug":"google/gemini-3-pro-preview","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":7678877.96491,"endTime":7682011.782537,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.001242","marketCost":"0.001242","generationId":"gen_01KGF39SRSQ5CWVF17GR4P29CK","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":57,"completion_tokens":18,"total_tokens":75,"cost":0.001242,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":76,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.001242},"system_fingerprint":"fp_4r8izhsq38","generationId":"gen_01KGF39SRSQ5CWVF17GR4P29CK"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 3.240620375s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1242
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"Oxu2MENhE0ZsrlGm","function":{"arguments":"{\"b\":3,\"a\":2}","name":"add"},"type":"function"},{"id":"jHpVWOzg44py3a4h","function":{"arguments":"{\"b\":3,\"a\":2}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"Oxu2MENhE0ZsrlGm","role":"tool"},{"content":"6","tool_call_id":"jHpVWOzg44py3a4h","role":"tool"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF39X286MHE27SNFKH25NC4","object":"chat.completion.chunk","created":1770033316,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_77ne7mn4wm"}
+
+ data: {"id":"gen_01KGF39X286MHE27SNFKH25NC4","object":"chat.completion.chunk","created":1770033316,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"content":"The sum of 2 and 3 is"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_77ne7mn4wm"}
+
+ data: {"id":"gen_01KGF39X286MHE27SNFKH25NC4","object":"chat.completion.chunk","created":1770033316,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"content":" 5, and the product of 2 and 3 is 6."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_77ne7mn4wm"}
+
+ data: {"id":"gen_01KGF39X286MHE27SNFKH25NC4","object":"chat.completion.chunk","created":1770033316,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":107,"promptTokenCount":219,"candidatesTokenCount":25,"totalTokenCount":351}},"gateway":{"routing":{"originalModelId":"google/gemini-3-pro-preview","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-3-pro-preview","internalResolvedModelId":"vertex:gemini-3-pro-preview","fallbacksAvailable":["google"],"internalReasoning":"Selected vertex as preferred provider for gemini-3-pro-preview. 1 fallback(s) available: google","planningReasoning":"System credentials planned for: vertex, google. Total execution order: vertex(system) ā google(system)","canonicalSlug":"google/gemini-3-pro-preview","finalProvider":"google","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":false,"error":"Please ensure that the number of function response parts is equal to the number of function call parts of the function call turn.","startTime":7682389.843352,"endTime":7682560.855095,"statusCode":400},{"provider":"google","internalModelId":"google:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":7682658.945631,"endTime":7685688.640771,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-3-pro-preview","canonicalSlug":"google/gemini-3-pro-preview","success":true,"providerAttemptCount":2,"providerAttempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":false,"error":"Please ensure that the number of function response parts is equal to the number of function call parts of the function call turn.","startTime":7682389.843352,"endTime":7682560.855095,"statusCode":400},{"provider":"google","internalModelId":"google:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":7682658.945631,"endTime":7685688.640771,"statusCode":200}]}],"totalProviderAttemptCount":2},"cost":"0.002022","marketCost":"0.002022","generationId":"gen_01KGF39X286MHE27SNFKH25NC4","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":219,"completion_tokens":25,"total_tokens":244,"cost":0.002022,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":107,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002022},"system_fingerprint":"fp_77ne7mn4wm","generationId":"gen_01KGF39X286MHE27SNFKH25NC4"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 3.595823375s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/simple.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/simple.yaml
new file mode 100644
index 000000000..821feca09
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 177
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"google/gemini-3-pro-preview","max_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF38WR2DQ7XVWAQPMSQN05J","object":"chat.completion","created":1770033284,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"message":{"role":"assistant","content":"The most common way to say \"hi\" in Portuguese is:\n\n**Oi**\n\nYou can also say **OlĆ”** (which is closer to \"hello\").","reasoning_details":[{"type":"reasoning.encrypted","data":"CtcGAY89a1/Vs+RSuBVpzJ1TJvRE/FtqFQVib99RvrHh+gb2EIdzDDZ/SY3ZVeQvQRZIOtEXdxlbjsymY95+YrKyX3B3sDmt7Y0hdpvDVQSQo7BymSD0/qtaPPexP57xCSzdyLZo08AKW5LCUmrBI15/XipH592d0XzRuidBu+EeAlTHMv3bwpwJaJ8DB4RoHhLpG8ueW73DsRnioUPYyQKnUK/8uov5qicTsNIiT67adu/wUBytqrDgRGmtiqw3MyQBaOG7xIEg8VUy8gTAVBKc3HFUh0m8d9+GbHshh2RgKyhA47cBxgef9hHH9fcM71mDXqgNJrZhv7vxgt4GOmVIF7e9iIx4lnYxi46WRlAchSO/rym7grFHNBAZ3D/uQoIp1VyoCyySIcLRVhLyNrU4c3IHWdOs6JuE+xbZiB3Flyccvg4oqiiaN4SOJXlP5+iAo9ASQmwHVy5e4j+/7Uo5G4D+pfxAdYwTT7cbGxLwHDZC13kcFfoi7YHawIghOLdcbQ4Y1wjkHbkP3vgp6zcTsQRw8PGZ8mPaHgMeZ3BGQn+q3jheqs3vcY0zazH9j2b1Yp4R2rcqyHqTpj1pV9BScW1g9dYuTRDjkzJbQxERZ2OrDTomVD6wPV76lldVGVeOOIRY/sNwl/VyXfyp4uJvqHTd6lz1A7JvUQDblT9GMvKmZKXlXW3uCqFroJpUGZVyFBxoNg4vo2vNZdpkCKikbX+irD58WxT8//oU9utaT5TmU7iVcGez3xeED8Pcfe8b4cDBnIBdNPDYJOjLXh5PFFJHJ7ad6Qzb+4FLdXnWl132D+uhuC3nQf7fPsrr8gf4yNzefuX8OjPgCGvobT56LusnH26ef8Vq7yYppYm8oz+JEVqXz2yydWWMwfJoCBESk96rNtdQ1fThaLrwGiz30NvOFZhBQ64f9MmTzt5/Ch97xfNBQNj4nCOzwOgsijXxOV0WG0W9zOjLVaL2StHURwyRNrCjDThoenOcOzRQiHIO+Y3ugEyp2k1dLIU93pILCZKmGmErUXVJxNOdPD/JNkfUDkioIvUDX9+To+cfmsx32Ynrm6auYsZzHI6ntFbu2Yw2S7iozfOVBER1ohInrt3djXS3gZn7NlaTlg71BQ3Lhr23As0Y","format":"google-gemini-v1","index":0}],"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":221,"promptTokenCount":9,"candidatesTokenCount":33,"totalTokenCount":263,"trafficType":"PROVISIONED_THROUGHPUT"}},"gateway":{"routing":{"originalModelId":"google/gemini-3-pro-preview","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-3-pro-preview","internalResolvedModelId":"vertex:gemini-3-pro-preview","fallbacksAvailable":["google"],"internalReasoning":"Selected vertex as preferred provider for gemini-3-pro-preview. 1 fallback(s) available: google","planningReasoning":"System credentials planned for: vertex, google. Total execution order: vertex(system) ā google(system)","canonicalSlug":"google/gemini-3-pro-preview","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":7028889.551463,"endTime":7033870.641762,"statusCode":200,"providerResponseId":"f5CAaZznMrj2mLAP-aa82AU"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-3-pro-preview","canonicalSlug":"google/gemini-3-pro-preview","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.003066","marketCost":"0.003066","generationId":"gen_01KGF38WR2DQ7XVWAQPMSQN05J","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":9,"completion_tokens":33,"total_tokens":42,"cost":0.003066,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":221,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.003066},"system_fingerprint":"fp_kece7x1dv2","generationId":"gen_01KGF38WR2DQ7XVWAQPMSQN05J"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 5.077063708s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/simple_streaming.yaml
new file mode 100644
index 000000000..a775f281b
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/simple_streaming.yaml
@@ -0,0 +1,42 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 231
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF391Q1MADSMMMS7RN0MPJX","object":"chat.completion.chunk","created":1770033289,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_s005gr6r3v"}
+
+ data: {"id":"gen_01KGF391Q1MADSMMMS7RN0MPJX","object":"chat.completion.chunk","created":1770033289,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"content":"The most common way to say \"hi\" in Portuguese is **\"Oi\"**.\n\nYou can also say **\"OlĆ”\"** (which is more like \"hello\")."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_s005gr6r3v"}
+
+ data: {"id":"gen_01KGF391Q1MADSMMMS7RN0MPJX","object":"chat.completion.chunk","created":1770033289,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"reasoning_details":[{"type":"reasoning.encrypted","data":"CikBjz1rX1dPuLSzjatsf+kEp2Ri1nfHbqwWCwH07OuC1ZuewqSVGPoPzgpfAY89a18bv4mLFvt3bZAdiEoaZ+mjKsSaNKkndIQFXlBX/7hCWWnr1+bAbThHMnH0oIh/4vTXgk8DVKR87b2jqz0KuQG/kFftlB+5jAH9Jiq5/n2JIbFm06nvcF0dlyoKZgGPPWtfUh80MPPeLg0AMzKvrsGiCeKISEhrD6sg11jcaV4dgc/eBV9iwvHXn1LQU3GtPAsNZ4H1ZJM2+49hgdR6sN4vu81IqEdPsBItnGmr4TBm4Gm90LBPvCkcoSb3bh3q41kuaAqSAQGPPWtfYRILvpzZWl2d/sialYcYOf3UGDEFKBuz8HHUo40bCo+HQuJTal05BxWjIEzS4+wNKYrEsmo65fYSq/W1VBPGJVWbySFHDILvcVbMLJriGdWQbpAtXRAi/EoxQYjctaLyV1H77smAtachR9b7fKBfAlccpyd6QqLRi55uBIIczarwv97rFs+ylW/T/2m8CpQBAY89a198U9DZKPUsXuUCZvugyKq7U4JFHcDNk8+2W9F22IOz/lRPP4mRMj2DnaeMEZvj8NlAgN+uPpIS7pBPMWCiTsNUdTp0ZXfGZid8B/M6DFVv/DiS62f+C9LyW93Y+YLltHz0HsYgqFAhNW/TbxLFwshqad8KSAwEUJspHG5VheRkyflEReRxpNFm9MX7FTIsAQrhAQGPPWtf1NKdz86iQg+9J+FwwgJmOemZh5b7nk1s4iVyI4+SRdy5n6lGIwM/RS4brolzexTvzZU4yJHDd3kPm4eEOrATOu7g6wW4Vsdw6+LA6RkX/+TTPZbt7JmWYVbws5YUJGdKD3ddEG9faoV+kxGun8mJDEOdCKVZUDRQtU07nKEa/R9/8xkJaNBv8GBs4TuOHB56wH9rIp4I1qvaW9DU6TlcxKhw8BdtpYbD6Gg3e6asqePEUEIAXeQ5eQUfgC5lDSXRD99j4j42y3tNiKNXY+h2TZc3SIc40ohsM5XzTwqzAQGPPWtfzWc0ZYfA/k2tbqLr/45Vpgn/1yfSC1kXi+ABfbLhzZR4oNnbBlBHcmEbBF3DokgxaI7WEbopj4zbm0ZsYNJVLxD0cGd/kV+CBKbCf4j7L1fCJKlI8Mnorq5Bgp8i28XWjCydjvRAoTT49cJp0LKnKHw2Hr95yMnKPIwlOiAtQ0IFOjNXbfWQSCp42fSXDofsoufZor01El8xVfsaIQTkJtCbyE/AjOwz25v4xsp/CnkBjz1rXw6jbdgKOjllJsnqicBq0+EJ8nM5HbD25Dj1klrIvslkr8/5YyV6Fk43IYUfpLJW63qj9/4/cuRTDWBmbwOYMbf0JJCC0vGZvlz0UbLH3gEFfElZ7D8KAjc6iQ71etnHkYAHfUHlMdJ/B7qJLvQGpN8w4H/A","format":"google-gemini-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_s005gr6r3v"}
+
+ data: {"id":"gen_01KGF391Q1MADSMMMS7RN0MPJX","object":"chat.completion.chunk","created":1770033289,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":223,"promptTokenCount":9,"candidatesTokenCount":35,"totalTokenCount":267,"trafficType":"ON_DEMAND"}},"gateway":{"routing":{"originalModelId":"google/gemini-3-pro-preview","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-3-pro-preview","internalResolvedModelId":"vertex:gemini-3-pro-preview","fallbacksAvailable":["google"],"internalReasoning":"Selected vertex as preferred provider for gemini-3-pro-preview. 1 fallback(s) available: google","planningReasoning":"System credentials planned for: vertex, google. Total execution order: vertex(system) ā google(system)","canonicalSlug":"google/gemini-3-pro-preview","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":1391831.603433,"endTime":1396730.275173,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-3-pro-preview","canonicalSlug":"google/gemini-3-pro-preview","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":1391831.603433,"endTime":1396730.275173,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.003114","marketCost":"0.003114","generationId":"gen_01KGF391Q1MADSMMMS7RN0MPJX","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":9,"completion_tokens":35,"total_tokens":44,"cost":0.003114,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":223,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.003114},"system_fingerprint":"fp_s005gr6r3v","generationId":"gen_01KGF391Q1MADSMMMS7RN0MPJX"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 5.130387417s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/tool.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/tool.yaml
new file mode 100644
index 000000000..0b8ff03b8
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 469
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF396RM9XH4DT3BKG6XYYC0","object":"chat.completion","created":1770033293,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"message":{"role":"assistant","content":null,"tool_calls":[{"id":"ixKHls2RfUCWLY8v","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence, Italy\"}"}}],"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":78,"promptTokenCount":28,"candidatesTokenCount":9,"totalTokenCount":115,"trafficType":"ON_DEMAND"}},"gateway":{"routing":{"originalModelId":"google/gemini-3-pro-preview","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-3-pro-preview","internalResolvedModelId":"vertex:gemini-3-pro-preview","fallbacksAvailable":["google"],"internalReasoning":"Selected vertex as preferred provider for gemini-3-pro-preview. 1 fallback(s) available: google","planningReasoning":"System credentials planned for: vertex, google. Total execution order: vertex(system) ā google(system)","canonicalSlug":"google/gemini-3-pro-preview","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":7659506.082926,"endTime":7662838.172979,"statusCode":200,"providerResponseId":"ipCAaZa6CeXDtfAPz8i1yAs"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-3-pro-preview","canonicalSlug":"google/gemini-3-pro-preview","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.0011","marketCost":"0.0011","generationId":"gen_01KGF396RM9XH4DT3BKG6XYYC0","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":28,"completion_tokens":9,"total_tokens":37,"cost":0.0011,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":78,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.0011},"system_fingerprint":"fp_oka8v3chzr","generationId":"gen_01KGF396RM9XH4DT3BKG6XYYC0"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.581068834s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 695
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"ixKHls2RfUCWLY8v","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"ixKHls2RfUCWLY8v","role":"tool"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF39A6QVKDAEJE16471HJ6N","object":"chat.completion","created":1770033295,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"message":{"role":"assistant","content":"The weather in Florence, Italy is currently 40°C.","provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"promptTokenCount":40,"candidatesTokenCount":14,"totalTokenCount":54,"trafficType":"PROVISIONED_THROUGHPUT"}},"gateway":{"routing":{"originalModelId":"google/gemini-3-pro-preview","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-3-pro-preview","internalResolvedModelId":"vertex:gemini-3-pro-preview","fallbacksAvailable":["google"],"internalReasoning":"Selected vertex as preferred provider for gemini-3-pro-preview. 1 fallback(s) available: google","planningReasoning":"System credentials planned for: vertex, google. Total execution order: vertex(system) ā google(system)","canonicalSlug":"google/gemini-3-pro-preview","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":1411069.913659,"endTime":1413447.981679,"statusCode":200,"providerResponseId":"jZCAaczqJ6HZmLAP9c_xgAs"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-3-pro-preview","canonicalSlug":"google/gemini-3-pro-preview","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.000248","marketCost":"0.000248","generationId":"gen_01KGF39A6QVKDAEJE16471HJ6N","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":40,"completion_tokens":14,"total_tokens":54,"cost":0.000248,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.000248},"system_fingerprint":"fp_qhfqfihebr","generationId":"gen_01KGF39A6QVKDAEJE16471HJ6N"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.530493166s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/tool_streaming.yaml
new file mode 100644
index 000000000..a8ce080bf
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gemini-3-pro-preview/tool_streaming.yaml
@@ -0,0 +1,81 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 523
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF39CMWTBAYWG62BTDA8EX5","object":"chat.completion.chunk","created":1770033298,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_n9t24sd6so"}
+
+ data: {"id":"gen_01KGF39CMWTBAYWG62BTDA8EX5","object":"chat.completion.chunk","created":1770033298,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"mbK8hEFBfrxbyEg3","type":"function","function":{"name":"weather","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_n9t24sd6so"}
+
+ data: {"id":"gen_01KGF39CMWTBAYWG62BTDA8EX5","object":"chat.completion.chunk","created":1770033298,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"location\":\"Florence, Italy\"}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_n9t24sd6so"}
+
+ data: {"id":"gen_01KGF39CMWTBAYWG62BTDA8EX5","object":"chat.completion.chunk","created":1770033298,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":72,"promptTokenCount":28,"candidatesTokenCount":9,"totalTokenCount":109,"trafficType":"ON_DEMAND"}},"gateway":{"routing":{"originalModelId":"google/gemini-3-pro-preview","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-3-pro-preview","internalResolvedModelId":"vertex:gemini-3-pro-preview","fallbacksAvailable":["google"],"internalReasoning":"Selected vertex as preferred provider for gemini-3-pro-preview. 1 fallback(s) available: google","planningReasoning":"System credentials planned for: vertex, google. Total execution order: vertex(system) ā google(system)","canonicalSlug":"google/gemini-3-pro-preview","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":7665475.024571,"endTime":7668255.526409,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-3-pro-preview","canonicalSlug":"google/gemini-3-pro-preview","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":7665475.024571,"endTime":7668255.526409,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.001028","marketCost":"0.001028","generationId":"gen_01KGF39CMWTBAYWG62BTDA8EX5","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":28,"completion_tokens":9,"total_tokens":37,"cost":0.001028,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":72,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.001028},"system_fingerprint":"fp_n9t24sd6so","generationId":"gen_01KGF39CMWTBAYWG62BTDA8EX5"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.918596875s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 749
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"mbK8hEFBfrxbyEg3","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"mbK8hEFBfrxbyEg3","role":"tool"}],"model":"google/gemini-3-pro-preview","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF39FC3KGNF4QFQ4V4694KD","object":"chat.completion.chunk","created":1770033301,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_et7g7hmqn5"}
+
+ data: {"id":"gen_01KGF39FC3KGNF4QFQ4V4694KD","object":"chat.completion.chunk","created":1770033301,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"content":"The current temperature in"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_et7g7hmqn5"}
+
+ data: {"id":"gen_01KGF39FC3KGNF4QFQ4V4694KD","object":"chat.completion.chunk","created":1770033301,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"content":" Florence, Italy is 40°C."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_et7g7hmqn5"}
+
+ data: {"id":"gen_01KGF39FC3KGNF4QFQ4V4694KD","object":"chat.completion.chunk","created":1770033301,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"promptTokenCount":40,"candidatesTokenCount":14,"totalTokenCount":54,"trafficType":"ON_DEMAND"}},"gateway":{"routing":{"originalModelId":"google/gemini-3-pro-preview","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-3-pro-preview","internalResolvedModelId":"vertex:gemini-3-pro-preview","fallbacksAvailable":["google"],"internalReasoning":"Selected vertex as preferred provider for gemini-3-pro-preview. 1 fallback(s) available: google","planningReasoning":"System credentials planned for: vertex, google. Total execution order: vertex(system) ā google(system)","canonicalSlug":"google/gemini-3-pro-preview","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":7668162.82122,"endTime":7670529.245941,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-3-pro-preview","canonicalSlug":"google/gemini-3-pro-preview","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":7668162.82122,"endTime":7670529.245941,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.000248","marketCost":"0.000248","generationId":"gen_01KGF39FC3KGNF4QFQ4V4694KD","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":40,"completion_tokens":14,"total_tokens":54,"cost":0.000248,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.000248},"system_fingerprint":"fp_et7g7hmqn5","generationId":"gen_01KGF39FC3KGNF4QFQ4V4694KD"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.526340125s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/multi_tool.yaml
new file mode 100644
index 000000000..8d713a40d
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 828
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"openai/gpt-5","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF38JKSTNNP061DTA2R1QR6","object":"chat.completion","created":1770033273,"model":"openai/gpt-5","choices":[{"index":0,"message":{"role":"assistant","content":null,"reasoning_details":[{"type":"reasoning.encrypted","data":"gAAAAABpgJB5sMVU3E5XyBIYkGVYX_idbwIgEl6hyzl37P25LBkPxPxtSA-z_vG-ub3Ht2lLorQuxuYXJw5TvvQljT1wPC9GtS-3qVZwt_QhReZWbhESWHryCcV1WyEPUZj8oG3nUVCuV917iOoZgfkRgLG8X9Oi5ezb_M42WqRmF1XWXL302fu3bJRy_jT8mmoiLnCmS1wXX_78058GTTjjJLGqTBPni0y7sZDDHpFgUsgpoWv3gF9X9OClhk3JOfuqgNYIVTS90C6pQ-JUHWX-9q-v34qMHs-E_QnaCYQLShf4Fa04N_DY0SphPoP1UaJMp6A1spu8WjCNLr4KjkFsq3QirbYcp9pwZj_N_XmbDRSTE4DXcqLKUafsUjpQC9bNiEvZ2oh95CRmMwHznVetnUTXsmxPj3p7x8MRer9NM1LMetWxMLz28oAnDq6T1xHu1nhSdHVBG7DpVIDeXN6PYA6BLrCiVuB3K3_pooysaNVwv05EPDrCrvYotlHdbDPiU_OsF9uClsKkTguYjfCqihV48xgYqAQJqU_guhAe3NSacal5sjGMG8OBp_QrcTsRmCG-pUJ0_YkU3BKxN-h3FBBjBfnZrmJIHkV17oIvqyfd4mr_apHg_tNQJlyNr14usvYzzp65IK1jJ4UXepLHyBJfuBh6U1j9EQmRd2gS9gwwT_pvN0TVZaZZs32Pxakgq0wBNkRrto41JRHbpdYOuL_pWpcJ8fceSVv4rYxn7qewym_XxX1hFRz3on638qI70UUmPc64m3DzB60l0O83FLqHvlNEGOR6SSogOZc3M0oX9Zll-kgi02fb9deA6_HrhrGjYzAUDFQEuyFwML4u2mquXz7e1hmyKede1kBPnnZxhNODgFbRZrW_qZPf6D8fcLLR5KZHdhO4NjSGigxt3vbdBqRRPVJw5Ci9v2kXJLAczXB8Ifv5Vz9BUdQgAh_QWHmrirtcjU4Y84m1wCskcIpf_F5pduuGedRj6pnmEyYATiNxl0XCy6RmPGKjwgAz5qcQzOyHz013e4QzzB5Etmm6B01_oYpHXgmsi84z_LrSCtGSQI8S8l4RpESzGqaqQ84apbFvw4xJuA3fJPekyN6HkhK0cnD_NVxrUiEsmnhnLNSpUkwjzFGFWbasYYQj6Rik2WNOhoHpmPXzVgJsdrp94MrUGXWEgdUDcIWnH8LFizamKnBNox1e1i_phBxrQLLzqfgN2HABOE9WyDEIfpOgJOX2RfDn6q_RQ9WM79hDZJD7RUap1bC0dlxqomi0fYVqyOoW0RQyQ-_mrBK4nYFVwfDaZwrWXNzTsFvtlJzN8O8-L5J6UTx-AhSNcnI35O3AuxbNyRC72HhVzN-A0Ae4SouL25ouc582Oy8M1xzs9RjlkoSIHZYAe2wzfvD9B7N0F2tbahD-MOHCbLctCFRb_S4gO29xZgeGgdXxyykq5il4vya6f1GmTfCC9Ktg4dsdmmqbSAXV9Ck0iUhg4cZVSNliyxxUMjJfDLt8ZO0f_UxrD2RCoZL7zwRgCAldl4ndkmotvTH_0HSRxmob1Q6AwgItkWU7GcGdk_7PLUho5332sVdKbQcpLVZQNyKOVtreej8EkH47b8wEvVJ6lz2lKNKEz9tyHRUlEPBjW3yb3YvO3wyfRkkqMMXFO_PEuhQ66ceSOHJJW2zmJuZepwBMUiez3sZph3o1zjvB7tHAY7YCaTjbh8urPaYjGUrLyVmvAkwEbQQwE1-vpyhoztrqOinvOm6fUyU0HsQuQIEqCUtFqO8G755g3I_cFrgfjmgRXMMvhKk4iQ61rOL2YAPNozSdCGNtplTJIhnb2xZC-gbtK8YwcbWz7B1k2bICxfgAhX7W9cOsnGnJwB-wS_vAkmjSZrHmrkAAAEjPLaemIGxhPzZ9sU6R2TLKHL6wOA0LthE5ltRY5PGnsCK7NFcsHDcyFWCGLH10UYfV1n5_uOvUMqsHlT8iHMA2y-W0DtdzDNeEUOZj5mDAwfdTAIoXJc5-wieyLp27uLJqmJ0ZvchRT2CcM0SC_mDNaYXlJyn5uavmUkp4Ykh2LGN54lFFzbcOsVcVLzpdQJ0u2QF4QXIbzHMnw8ipejfMaN2zkXRGsex9BXcf9fIOxwPH8LTsLRArUz--pl8wq8x2_ZyRNC5ZPtZrWr3lTokTqXrb8gASoIchRTZDV8fQdPIPXIJE4A-Dn-8Hfrxnf63IKRoFv4ENTzOoycoNH4kyCh4LQSInGFeE5vAa3Iq_ctdHf6LlVnoURnZdrmC_c03UMJjv671ZYbzuS76jKRTAJF7PnJhDdAhV-xvZmRKzJpJ4k_ZmN9O19iXZVVv4ofjn3m0iOWY8N61suLBb9wErE0PJxzNQnLBFSXuC3qrd9IrVzEMUOsMloPH6bB-zGlRQP_gY3LzZ4tEF70ZuqIdwAYgjKGc9LqXfz0d5hXLLPE0MeJxiCJFuHyUCgPphf8gfCw6lw0gz7KiH87aXBbOTwcUl2bT6pDDmKSkZQPUv67c0JoB0j5IsH67XBFhYZHiyenTddXJHSKHXnLlhdZCifIDaYXElPZLdWT5SZ3Y_i1AAaLOk-h2esjagpMOWRZMzY97KHDINIMiUcW_aE5IrsGWkP8jnHu-rDHXU2L9VOzErnTMz8b-DXg==","id":"rs_09ce24a3ef4ef4c30169809075d9c881909a0602f2f9b94079","format":"openai-responses-v1","index":0}],"tool_calls":[{"id":"call_hw6yjnBO12c7jlYo4Ug0REvD","type":"function","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"}},{"id":"call_1DofUzAYzaNZecbxfrt2sRSv","type":"function","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"}}],"provider_metadata":{"openai":{"responseId":"resp_09ce24a3ef4ef4c30169809075837481908f0f2e352bb0536c","serviceTier":"default"},"gateway":{"routing":{"originalModelId":"openai/gpt-5","resolvedProvider":"openai","resolvedProviderApiModelId":"gpt-5-2025-08-07","internalResolvedModelId":"openai:gpt-5-2025-08-07","fallbacksAvailable":["azure"],"internalReasoning":"Selected openai as preferred provider for gpt-5. 1 fallback(s) available: azure","planningReasoning":"System credentials planned for: openai, azure. Total execution order: openai(system) ā azure(system)","canonicalSlug":"openai/gpt-5","finalProvider":"openai","attempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":1376272.617242,"endTime":1380180.418282,"statusCode":200,"providerResponseId":"resp_09ce24a3ef4ef4c30169809075837481908f0f2e352bb0536c"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"openai/gpt-5","canonicalSlug":"openai/gpt-5","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.00609","marketCost":"0.00609","generationId":"gen_01KGF38JKSTNNP061DTA2R1QR6","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":56,"completion_tokens":346,"total_tokens":402,"cost":0.00609,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":256,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.00609},"system_fingerprint":"fp_z6pyhzzwli","generationId":"gen_01KGF38JKSTNNP061DTA2R1QR6"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.998469542s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 4078
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_hw6yjnBO12c7jlYo4Ug0REvD","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"call_1DofUzAYzaNZecbxfrt2sRSv","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant","reasoning_details":[{"data":"gAAAAABpgJB5sMVU3E5XyBIYkGVYX_idbwIgEl6hyzl37P25LBkPxPxtSA-z_vG-ub3Ht2lLorQuxuYXJw5TvvQljT1wPC9GtS-3qVZwt_QhReZWbhESWHryCcV1WyEPUZj8oG3nUVCuV917iOoZgfkRgLG8X9Oi5ezb_M42WqRmF1XWXL302fu3bJRy_jT8mmoiLnCmS1wXX_78058GTTjjJLGqTBPni0y7sZDDHpFgUsgpoWv3gF9X9OClhk3JOfuqgNYIVTS90C6pQ-JUHWX-9q-v34qMHs-E_QnaCYQLShf4Fa04N_DY0SphPoP1UaJMp6A1spu8WjCNLr4KjkFsq3QirbYcp9pwZj_N_XmbDRSTE4DXcqLKUafsUjpQC9bNiEvZ2oh95CRmMwHznVetnUTXsmxPj3p7x8MRer9NM1LMetWxMLz28oAnDq6T1xHu1nhSdHVBG7DpVIDeXN6PYA6BLrCiVuB3K3_pooysaNVwv05EPDrCrvYotlHdbDPiU_OsF9uClsKkTguYjfCqihV48xgYqAQJqU_guhAe3NSacal5sjGMG8OBp_QrcTsRmCG-pUJ0_YkU3BKxN-h3FBBjBfnZrmJIHkV17oIvqyfd4mr_apHg_tNQJlyNr14usvYzzp65IK1jJ4UXepLHyBJfuBh6U1j9EQmRd2gS9gwwT_pvN0TVZaZZs32Pxakgq0wBNkRrto41JRHbpdYOuL_pWpcJ8fceSVv4rYxn7qewym_XxX1hFRz3on638qI70UUmPc64m3DzB60l0O83FLqHvlNEGOR6SSogOZc3M0oX9Zll-kgi02fb9deA6_HrhrGjYzAUDFQEuyFwML4u2mquXz7e1hmyKede1kBPnnZxhNODgFbRZrW_qZPf6D8fcLLR5KZHdhO4NjSGigxt3vbdBqRRPVJw5Ci9v2kXJLAczXB8Ifv5Vz9BUdQgAh_QWHmrirtcjU4Y84m1wCskcIpf_F5pduuGedRj6pnmEyYATiNxl0XCy6RmPGKjwgAz5qcQzOyHz013e4QzzB5Etmm6B01_oYpHXgmsi84z_LrSCtGSQI8S8l4RpESzGqaqQ84apbFvw4xJuA3fJPekyN6HkhK0cnD_NVxrUiEsmnhnLNSpUkwjzFGFWbasYYQj6Rik2WNOhoHpmPXzVgJsdrp94MrUGXWEgdUDcIWnH8LFizamKnBNox1e1i_phBxrQLLzqfgN2HABOE9WyDEIfpOgJOX2RfDn6q_RQ9WM79hDZJD7RUap1bC0dlxqomi0fYVqyOoW0RQyQ-_mrBK4nYFVwfDaZwrWXNzTsFvtlJzN8O8-L5J6UTx-AhSNcnI35O3AuxbNyRC72HhVzN-A0Ae4SouL25ouc582Oy8M1xzs9RjlkoSIHZYAe2wzfvD9B7N0F2tbahD-MOHCbLctCFRb_S4gO29xZgeGgdXxyykq5il4vya6f1GmTfCC9Ktg4dsdmmqbSAXV9Ck0iUhg4cZVSNliyxxUMjJfDLt8ZO0f_UxrD2RCoZL7zwRgCAldl4ndkmotvTH_0HSRxmob1Q6AwgItkWU7GcGdk_7PLUho5332sVdKbQcpLVZQNyKOVtreej8EkH47b8wEvVJ6lz2lKNKEz9tyHRUlEPBjW3yb3YvO3wyfRkkqMMXFO_PEuhQ66ceSOHJJW2zmJuZepwBMUiez3sZph3o1zjvB7tHAY7YCaTjbh8urPaYjGUrLyVmvAkwEbQQwE1-vpyhoztrqOinvOm6fUyU0HsQuQIEqCUtFqO8G755g3I_cFrgfjmgRXMMvhKk4iQ61rOL2YAPNozSdCGNtplTJIhnb2xZC-gbtK8YwcbWz7B1k2bICxfgAhX7W9cOsnGnJwB-wS_vAkmjSZrHmrkAAAEjPLaemIGxhPzZ9sU6R2TLKHL6wOA0LthE5ltRY5PGnsCK7NFcsHDcyFWCGLH10UYfV1n5_uOvUMqsHlT8iHMA2y-W0DtdzDNeEUOZj5mDAwfdTAIoXJc5-wieyLp27uLJqmJ0ZvchRT2CcM0SC_mDNaYXlJyn5uavmUkp4Ykh2LGN54lFFzbcOsVcVLzpdQJ0u2QF4QXIbzHMnw8ipejfMaN2zkXRGsex9BXcf9fIOxwPH8LTsLRArUz--pl8wq8x2_ZyRNC5ZPtZrWr3lTokTqXrb8gASoIchRTZDV8fQdPIPXIJE4A-Dn-8Hfrxnf63IKRoFv4ENTzOoycoNH4kyCh4LQSInGFeE5vAa3Iq_ctdHf6LlVnoURnZdrmC_c03UMJjv671ZYbzuS76jKRTAJF7PnJhDdAhV-xvZmRKzJpJ4k_ZmN9O19iXZVVv4ofjn3m0iOWY8N61suLBb9wErE0PJxzNQnLBFSXuC3qrd9IrVzEMUOsMloPH6bB-zGlRQP_gY3LzZ4tEF70ZuqIdwAYgjKGc9LqXfz0d5hXLLPE0MeJxiCJFuHyUCgPphf8gfCw6lw0gz7KiH87aXBbOTwcUl2bT6pDDmKSkZQPUv67c0JoB0j5IsH67XBFhYZHiyenTddXJHSKHXnLlhdZCifIDaYXElPZLdWT5SZ3Y_i1AAaLOk-h2esjagpMOWRZMzY97KHDINIMiUcW_aE5IrsGWkP8jnHu-rDHXU2L9VOzErnTMz8b-DXg==","format":"openai-responses-v1","id":"rs_09ce24a3ef4ef4c30169809075d9c881909a0602f2f9b94079","index":0,"type":"reasoning.encrypted"}]},{"content":"5","tool_call_id":"call_hw6yjnBO12c7jlYo4Ug0REvD","role":"tool"},{"content":"6","tool_call_id":"call_1DofUzAYzaNZecbxfrt2sRSv","role":"tool"}],"model":"openai/gpt-5","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF38PH89YBGB4JEVM3QY13Q","object":"chat.completion","created":1770033274,"model":"openai/gpt-5","choices":[{"index":0,"message":{"role":"assistant","content":"Sum: 5\nProduct: 6","provider_metadata":{"openai":{"responseId":"resp_09ce24a3ef4ef4c3016980907989e48190add2b3ea521eefd8","serviceTier":"default"},"gateway":{"routing":{"originalModelId":"openai/gpt-5","resolvedProvider":"openai","resolvedProviderApiModelId":"gpt-5-2025-08-07","internalResolvedModelId":"openai:gpt-5-2025-08-07","fallbacksAvailable":["azure"],"internalReasoning":"Selected openai as preferred provider for gpt-5. 1 fallback(s) available: azure","planningReasoning":"System credentials planned for: openai, azure. Total execution order: openai(system) ā azure(system)","canonicalSlug":"openai/gpt-5","finalProvider":"openai","attempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":262916.844804,"endTime":263772.252753,"statusCode":200,"providerResponseId":"resp_09ce24a3ef4ef4c3016980907989e48190add2b3ea521eefd8"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"openai/gpt-5","canonicalSlug":"openai/gpt-5","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.00070875","marketCost":"0.00070875","generationId":"gen_01KGF38PH89YBGB4JEVM3QY13Q","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":463,"completion_tokens":13,"total_tokens":476,"cost":0.00070875,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.00070875},"system_fingerprint":"fp_md8g0mkmrp","generationId":"gen_01KGF38PH89YBGB4JEVM3QY13Q"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 961.776042ms
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/multi_tool_streaming.yaml
new file mode 100644
index 000000000..f2251f032
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/multi_tool_streaming.yaml
@@ -0,0 +1,101 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 865
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"openai/gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF38QHY01RX510GTJVENPPB","object":"chat.completion.chunk","created":1770033274,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_lwams5xjm0"}
+
+ data: {"id":"gen_01KGF38QHY01RX510GTJVENPPB","object":"chat.completion.chunk","created":1770033274,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning_details":[{"type":"reasoning.encrypted","data":"gAAAAABpgJB6xgaIX4YGTj3EZimfLMfl7lZ7SJq0aBMWfGDeorXxt6sRPjllCKcFat69Q1kpuEDG1tvuIG_6OxUZHOP_noSA63nkkhTluixdSHPde3XgwYgrm01hBIphFo1ztgQMsVXZaqNGBJKfB35qJ7zSKEFXWcB6olUNA4UUXTup_nH8KrNf0_JcRd4JmIXeaQTTaNLYxeUNljoVsLun6RwBzKf2sDmMFqa8wdE5v159EsaN20EgWQnJGlWdyWEZBixffGM4cXbWIpmZRCv8TCy4dYMh3Nz8FQt7JbWJvCWQskP_b3AFm3TV-h8yUBFhdXRYAeZxtIZsBmjCZZtwDPGnKJ3tLtSnQ3PtlYFn1l0vvPgHh7mdmnhdbWtkUh3hQozmpwGYE5G0LE1XlEQ9KqdR6_ERfztdnbWnxJqAly_m5uXFu6ymcMDmZhkdFvRM1M8923TpttfrkNlzsQM2pzRyZYhATSrBz8eMgJY7me3UHXo3FlGnf0Capm2MNNLVytVv0mgqa8WEMhPzpuga1kbqKt884QqnjHgozx0DYM68uOwTOlMBdRSf6MCE5aqn4fYK7sp3_ZclUNtDr7cM8Pz5GJX3dh_py69qCStpAhptt0smksFcHGezX9zrDehJ9bPvW6gTK4aBKUAndr6SXQ22Boa0kRTo2YWU6mNMr0yNQomEoupdUvc5FtsJ6PiaOz7rTHDS10SCZAvSv0cE2rdVAmh_j-2uDfYkKBs_wPDiNSXCdmIBtO8w4QFABeZQut22nlPTA7a6zV2-GV5m_7FumT6mn92tVW39uuZaWLgJWqa_KADeWM35JQTHrzOOLz54vm4M","id":"rs_0023798544b250b9016980907aebec81948e9042e8de044015","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_lwams5xjm0"}
+
+ data: {"id":"gen_01KGF38QHY01RX510GTJVENPPB","object":"chat.completion.chunk","created":1770033274,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_tHpxKCS6xnVW3HBEkBww7S9T","type":"function","function":{"name":"add","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_lwams5xjm0"}
+
+ data: {"id":"gen_01KGF38QHY01RX510GTJVENPPB","object":"chat.completion.chunk","created":1770033274,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"a\":2,\"b\":3}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_lwams5xjm0"}
+
+ data: {"id":"gen_01KGF38QHY01RX510GTJVENPPB","object":"chat.completion.chunk","created":1770033274,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_qj0i1JW7dlNDPv5uNW5Tq6lO","type":"function","function":{"name":"multiply","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_lwams5xjm0"}
+
+ data: {"id":"gen_01KGF38QHY01RX510GTJVENPPB","object":"chat.completion.chunk","created":1770033274,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"a\":2,\"b\":3}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_lwams5xjm0"}
+
+ data: {"id":"gen_01KGF38QHY01RX510GTJVENPPB","object":"chat.completion.chunk","created":1770033274,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"provider_metadata":{"openai":{"responseId":"resp_0023798544b250b9016980907a944c8194aa354cf54822893e","serviceTier":"default"},"gateway":{"routing":{"originalModelId":"openai/gpt-5","resolvedProvider":"openai","resolvedProviderApiModelId":"gpt-5-2025-08-07","internalResolvedModelId":"openai:gpt-5-2025-08-07","fallbacksAvailable":["azure"],"internalReasoning":"Selected openai as preferred provider for gpt-5. 1 fallback(s) available: azure","planningReasoning":"System credentials planned for: openai, azure. Total execution order: openai(system) ā azure(system)","canonicalSlug":"openai/gpt-5","finalProvider":"openai","attempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":7023589.520205,"endTime":7023819.54204,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"openai/gpt-5","canonicalSlug":"openai/gpt-5","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":7023589.520205,"endTime":7023819.54204,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.0049675","marketCost":"0.0049675","generationId":"gen_01KGF38QHY01RX510GTJVENPPB","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":54,"completion_tokens":298,"total_tokens":352,"cost":0.0049675,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":192,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.0049675},"system_fingerprint":"fp_lwams5xjm0","generationId":"gen_01KGF38QHY01RX510GTJVENPPB"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 408.927458ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2299
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"call_tHpxKCS6xnVW3HBEkBww7S9T","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"call_qj0i1JW7dlNDPv5uNW5Tq6lO","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant","reasoning_details":[{"data":"gAAAAABpgJB6xgaIX4YGTj3EZimfLMfl7lZ7SJq0aBMWfGDeorXxt6sRPjllCKcFat69Q1kpuEDG1tvuIG_6OxUZHOP_noSA63nkkhTluixdSHPde3XgwYgrm01hBIphFo1ztgQMsVXZaqNGBJKfB35qJ7zSKEFXWcB6olUNA4UUXTup_nH8KrNf0_JcRd4JmIXeaQTTaNLYxeUNljoVsLun6RwBzKf2sDmMFqa8wdE5v159EsaN20EgWQnJGlWdyWEZBixffGM4cXbWIpmZRCv8TCy4dYMh3Nz8FQt7JbWJvCWQskP_b3AFm3TV-h8yUBFhdXRYAeZxtIZsBmjCZZtwDPGnKJ3tLtSnQ3PtlYFn1l0vvPgHh7mdmnhdbWtkUh3hQozmpwGYE5G0LE1XlEQ9KqdR6_ERfztdnbWnxJqAly_m5uXFu6ymcMDmZhkdFvRM1M8923TpttfrkNlzsQM2pzRyZYhATSrBz8eMgJY7me3UHXo3FlGnf0Capm2MNNLVytVv0mgqa8WEMhPzpuga1kbqKt884QqnjHgozx0DYM68uOwTOlMBdRSf6MCE5aqn4fYK7sp3_ZclUNtDr7cM8Pz5GJX3dh_py69qCStpAhptt0smksFcHGezX9zrDehJ9bPvW6gTK4aBKUAndr6SXQ22Boa0kRTo2YWU6mNMr0yNQomEoupdUvc5FtsJ6PiaOz7rTHDS10SCZAvSv0cE2rdVAmh_j-2uDfYkKBs_wPDiNSXCdmIBtO8w4QFABeZQut22nlPTA7a6zV2-GV5m_7FumT6mn92tVW39uuZaWLgJWqa_KADeWM35JQTHrzOOLz54vm4M","format":"openai-responses-v1","id":"rs_0023798544b250b9016980907aebec81948e9042e8de044015","index":0,"type":"reasoning.encrypted"}]},{"content":"5","tool_call_id":"call_tHpxKCS6xnVW3HBEkBww7S9T","role":"tool"},{"content":"6","tool_call_id":"call_qj0i1JW7dlNDPv5uNW5Tq6lO","role":"tool"}],"model":"openai/gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF38VW9EJPCTC0TED93SGM2","object":"chat.completion.chunk","created":1770033279,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_rb8lymwxwp"}
+
+ data: {"id":"gen_01KGF38VW9EJPCTC0TED93SGM2","object":"chat.completion.chunk","created":1770033279,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"Add"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_rb8lymwxwp"}
+
+ data: {"id":"gen_01KGF38VW9EJPCTC0TED93SGM2","object":"chat.completion.chunk","created":1770033279,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_rb8lymwxwp"}
+
+ data: {"id":"gen_01KGF38VW9EJPCTC0TED93SGM2","object":"chat.completion.chunk","created":1770033279,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_rb8lymwxwp"}
+
+ data: {"id":"gen_01KGF38VW9EJPCTC0TED93SGM2","object":"chat.completion.chunk","created":1770033279,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"5"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_rb8lymwxwp"}
+
+ data: {"id":"gen_01KGF38VW9EJPCTC0TED93SGM2","object":"chat.completion.chunk","created":1770033279,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_rb8lymwxwp"}
+
+ data: {"id":"gen_01KGF38VW9EJPCTC0TED93SGM2","object":"chat.completion.chunk","created":1770033279,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"Multiply"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_rb8lymwxwp"}
+
+ data: {"id":"gen_01KGF38VW9EJPCTC0TED93SGM2","object":"chat.completion.chunk","created":1770033279,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_rb8lymwxwp"}
+
+ data: {"id":"gen_01KGF38VW9EJPCTC0TED93SGM2","object":"chat.completion.chunk","created":1770033279,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_rb8lymwxwp"}
+
+ data: {"id":"gen_01KGF38VW9EJPCTC0TED93SGM2","object":"chat.completion.chunk","created":1770033279,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"6"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_rb8lymwxwp"}
+
+ data: {"id":"gen_01KGF38VW9EJPCTC0TED93SGM2","object":"chat.completion.chunk","created":1770033279,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"provider_metadata":{"openai":{"responseId":"resp_0023798544b250b9016980907efc7c81948203b5d78adfea6b","serviceTier":"default"},"gateway":{"routing":{"originalModelId":"openai/gpt-5","resolvedProvider":"openai","resolvedProviderApiModelId":"gpt-5-2025-08-07","internalResolvedModelId":"openai:gpt-5-2025-08-07","fallbacksAvailable":["azure"],"internalReasoning":"Selected openai as preferred provider for gpt-5. 1 fallback(s) available: azure","planningReasoning":"System credentials planned for: openai, azure. Total execution order: openai(system) ā azure(system)","canonicalSlug":"openai/gpt-5","finalProvider":"openai","attempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":3192786.860293,"endTime":3193009.179478,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"openai/gpt-5","canonicalSlug":"openai/gpt-5","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":3192786.860293,"endTime":3193009.179478,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.000345","marketCost":"0.000345","generationId":"gen_01KGF38VW9EJPCTC0TED93SGM2","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":172,"completion_tokens":13,"total_tokens":185,"cost":0.000345,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.000345},"system_fingerprint":"fp_rb8lymwxwp","generationId":"gen_01KGF38VW9EJPCTC0TED93SGM2"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 315.780916ms
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/simple.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/simple.yaml
new file mode 100644
index 000000000..1fec0eebb
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 173
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"openai/gpt-5","max_completion_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF3857W5E69F2H2ANCE2CYB","object":"chat.completion","created":1770033258,"model":"openai/gpt-5","choices":[{"index":0,"message":{"role":"assistant","content":"OlĆ”!","reasoning_details":[{"type":"reasoning.encrypted","data":"gAAAAABpgJBqe4UanBDshmkUO5UeBgKTle4JTA6JRhnoTGSFte1-ryTvUUbT5rmqGZ7FNrxFvny6dsrNnl1pd4YxeeFus-r67hkBoXsTVYnvct-B0l_CJHcuIZGAD0KSmHfXF0VozKzfZ8Lir1W5zaRJjS_o06nJ-YlqE-V__aYAPeSAhqdscK2B0AJZH4auLrNQolMQq-9d-A7SMnqComX-a1dpu8dZug7-EN9DrypPQqfrBg311Wf4Od2HNwmZS_SqAvOofhi6gkcN2p8MqSiWZNKJRDAJjC_cJsGJ-LQ3tmyPJEzclcMbjehRvjT_IDk0qKqEJqWLSLiDbTH6QaXvSTBQAaSUT8QB6_p42tstR_Jhelyhy1GSfYyny__5FrEmoqLE4sxu16Z1nEdE8MYvcJaUl0KT5Q32GziBMefLQQq9wwhcx6rXJUc29dt6xvntz__4w_kmJismJ8Etb1eVlSLtZwNGF0OyO6K7jar7EL93mbxjmpzu4olDI93EnyxiEDmpz6UOSjFbq-Ey5Kw8AL_L9TwgIMXgLrG-UYYXyzXRhyIL_hWAzMHhcyQs1cvm_RaDmCRC_zFGyKE3cd4QDxC4mnzru7vhWSykmT4A8VyBm57hhxk7wEFxz0_KDfnmrSCUxZiMwGVujBWY6BeqzNd-fF1OvLrYiTmyLzRql_mQ4ED6WeFtq3bFGfp4VdLqJ7Huzg7r0_7o5mQwQ3JpjWE_iay8JtHQfsFXuFCmH_VRdA604UOsuYLdnoGej4hES3jqECSwvJQQXNASQyJbQ2_uGsG1C56IlCzE-vDhqp2PShFoYvEDJ3_gb6TdgiF0ASS3NyFq5PIa1J2zTk3gRJnXkYGgO4kD_iHpkTKhn75LEFLOCuWb4DBpB8qHIUDPHU8odqcGLPjng7NKat7wp5PQGQRVJ_8ulRxyLf5_rP85jB5n_eNDg1MXIO7KALnJE0X9303JThanVo9c7hgvmgE_dbwNbmdzYasxIqYpTH524aoW4Pv3Py7C13Y4PH8WeWY5PeKoEEcyeleiBC1YO1G25JG1e91p-HcOcGWxGHzmln74j9H_LO16zqJias3tT4gRLAphcrHe-a6Ao7pFxwdut9Dw2Lg_79zGR5h5gjN8LBaCJSwMg-pcZ-V1_TAbFCjbeCYfze7ndt9OWOXjS2T05xKAal_21dveRfiuK7-6phUWQ7TgruezFhpPQXoOp8sXHpieyRR8K3_DYGm4qCFbtqUM_SReW2m7qr805a-C5OaDurcQmq--ex8ORV4y6YxD2pA0uriVy60L8vTwX3o82fIhjxvkBNsR1wwjb0puBzUfxX_hvLbbZ8SV1UeNwe0tsnCD0TOtTLczGreq3HkSy25_JQ==","id":"rs_0195d9d352e85fe40169809068318c8190b2bbf966d0dcd881","format":"openai-responses-v1","index":0}],"provider_metadata":{"openai":{"responseId":"resp_0195d9d352e85fe40169809067d3bc8190a9e940c7bf350bb4","serviceTier":"default"},"gateway":{"routing":{"originalModelId":"openai/gpt-5","resolvedProvider":"openai","resolvedProviderApiModelId":"gpt-5-2025-08-07","internalResolvedModelId":"openai:gpt-5-2025-08-07","fallbacksAvailable":["azure"],"internalReasoning":"Selected openai as preferred provider for gpt-5. 1 fallback(s) available: azure","planningReasoning":"System credentials planned for: openai, azure. Total execution order: openai(system) ā azure(system)","canonicalSlug":"openai/gpt-5","finalProvider":"openai","attempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":435303.593243,"endTime":437939.710829,"statusCode":200,"providerResponseId":"resp_0195d9d352e85fe40169809067d3bc8190a9e940c7bf350bb4"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"openai/gpt-5","canonicalSlug":"openai/gpt-5","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.00168375","marketCost":"0.00168375","generationId":"gen_01KGF3857W5E69F2H2ANCE2CYB","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":19,"completion_tokens":102,"total_tokens":121,"cost":0.00168375,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":64,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.00168375},"system_fingerprint":"fp_7r70i7ytcp","generationId":"gen_01KGF3857W5E69F2H2ANCE2CYB"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.791494792s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/simple_streaming.yaml
new file mode 100644
index 000000000..620cf9ab2
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/simple_streaming.yaml
@@ -0,0 +1,44 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 227
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"openai/gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF387XY51D0GDDRCM6KB8NB","object":"chat.completion.chunk","created":1770033258,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_tmpp8eb0yq"}
+
+ data: {"id":"gen_01KGF387XY51D0GDDRCM6KB8NB","object":"chat.completion.chunk","created":1770033258,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning_details":[{"type":"reasoning.encrypted","data":"gAAAAABpgJBr1JtCCwq4H63wpwrzBisIFa5cozvaVKPCSa_QKdqiKVGM1bH7JXlt53SbT0JsAPDQ_zh4dp6N57-9-WHBZGeFpXVhBWOVjECwI-Sx19ug89zVfZf0Xc7GmgO2C6uR35S0kkVN76bxn8_4ofEGjaGB_P-yjp6oLE4wLzAkH082bkzjww6Yv-2Hqw1FSJsdzCEIuf_FwQkoFPnRdBb5PPPGfyRnIAiS9lFGsMLEA1k8VpOfAWsM5q_UR_pJ8YAFK9MG8gPH8qsaG9rMZSLq5kPoz6lkbX3ZEsBcnpIzJLoYGIKRHPQFXehUxj1ml0hy38aNBv22zgZc0bvQUcM7dsnX-4iaNrUa2YskUJ7TPPuaHGR79KBIwfv0qqFiFDdaa38pJEM_-gAKIv2JcBoNZnui6bCEFNIcyTn-sDU9lhqfbXvFt7jnu7ZNV4kCqe8mhrC3x4V_n7ip2Gd_nA849tPiQmeGlMAgGUiBR3-dGOo-quuJp1nBWSiUvj5DisGkI8NlG_-lAPaVQQfjCc32bn3KY2Ch5a5RltI-DJuCzvpcrDkl4RZIeMoJfaQHUImhpmpZn3Y05ckwCdy1n0difkQIXPgNGcbVXLW5RD7xYDC375nYL4qHfbIWxjPjVv7Jsc8jMWjMhHWC_XCDdon4BhZ9LSj70ppMxkaxl3wgZW8o-s1xeSOM-AbviX_ZBjj63WfeTsUS24-tRDRmfbVSApDHbt7GVJMRr-7AsNZkvuDKMC-URk5Omp8eXJVzhaPnaQVhYPyh3jYmPHWbldKPiu6HZ2QZksn-tIM4M3rse2wJXf4ffk8rbBCcsJPIgT-R9cfq","id":"rs_04b3b5ea2112e2f2016980906b0aa4819087bc5b624622f5c1","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_tmpp8eb0yq"}
+
+ data: {"id":"gen_01KGF387XY51D0GDDRCM6KB8NB","object":"chat.completion.chunk","created":1770033258,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"OlĆ”"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_tmpp8eb0yq"}
+
+ data: {"id":"gen_01KGF387XY51D0GDDRCM6KB8NB","object":"chat.completion.chunk","created":1770033258,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"!"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_tmpp8eb0yq"}
+
+ data: {"id":"gen_01KGF387XY51D0GDDRCM6KB8NB","object":"chat.completion.chunk","created":1770033258,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"provider_metadata":{"openai":{"responseId":"resp_04b3b5ea2112e2f2016980906a921c81908b97d5d38611d5a6","serviceTier":"default"},"gateway":{"routing":{"originalModelId":"openai/gpt-5","resolvedProvider":"openai","resolvedProviderApiModelId":"gpt-5-2025-08-07","internalResolvedModelId":"openai:gpt-5-2025-08-07","fallbacksAvailable":["azure"],"internalReasoning":"Selected openai as preferred provider for gpt-5. 1 fallback(s) available: azure","planningReasoning":"System credentials planned for: openai, azure. Total execution order: openai(system) ā azure(system)","canonicalSlug":"openai/gpt-5","finalProvider":"openai","attempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":356384.393513,"endTime":356580.787605,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"openai/gpt-5","canonicalSlug":"openai/gpt-5","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":356384.393513,"endTime":356580.787605,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.00148375","marketCost":"0.00148375","generationId":"gen_01KGF387XY51D0GDDRCM6KB8NB","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":19,"completion_tokens":82,"total_tokens":101,"cost":0.00148375,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":64,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.00148375},"system_fingerprint":"fp_tmpp8eb0yq","generationId":"gen_01KGF387XY51D0GDDRCM6KB8NB"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 284.897458ms
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/tool.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/tool.yaml
new file mode 100644
index 000000000..b1ffe90a9
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 465
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"openai/gpt-5","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF389FA00FX9W76TJBD2FY0","object":"chat.completion","created":1770033261,"model":"openai/gpt-5","choices":[{"index":0,"message":{"role":"assistant","content":null,"reasoning_details":[{"type":"reasoning.encrypted","data":"gAAAAABpgJBt9rDWBVUu57Qp4eDPgvhNl_yejTP7GQIvS9aR9c0rc2udBHMKWf6Lov1QwiEeQbCc8LROQ_SbUEvfyEl-9PofdGalnrJON5sqNjhFmugyAnTzQwIbCLzHhViPQYcKTeDxYUNkLO-WUzh9UcgCE3H9-JaGFMFgvpEtK2izjoSXQAfcM4N4TpIjSZVLKCARs9L3jzHHdIMx1God2c7H0MErV3MDZ_7J_xlIDaVOQPKOOMzVO6EjBEWH9TQn_C3f2h5bm6YphGwIfcI7TxOmQVmf7NV0r9e5Tl0v2NQ6L5alFvBllJiKLOsmO6jShYoPT_i119sexG8bSw0w8qqlOvJJxA3nSmKgimH9TJXIynwqntgKw2sf3TUov2ZcXBXuuWEvwwuzvJZ-IblbQ4tp3voRndpGGLL5RaUAnVJxsawXAC7ghykRDhuqBywJVrc0HuNZKsl0qLjEi22IYXAhdbVerM84pD1IMgA-9XbzPryB6R6vvwk6UBQH7H35sSIywXRK0pWMJftKwUIfh87K8iPyt2sdvdxFgeCv1zygTwsvRNIyxrdLznmOlPPEmgeapkBzXMnpnhkIDRkm0q1owi849hYpArAr5dP9KonpVSkJEx_hO4Nu125WOtKG6kt59lWzVy5ntGaQbQx0Y9Ekg-YrVAt0MRBDTHbyYFvg01tRDT5qX7RTjVrxcnBJaS4jiHsE3ThGQCvlyUKDLrBD891lSuLZHJ-b_WDXiAZW63-INaU6dm7rkw0-kCCg6f02WEiTbwrUI3la4iJ_OHvO5dX8HMzO566TT_VPay9vmSAzBcO9vYyJHqAahlce6fc8HSC6yM4FmArFa7fAI24qzACBtcwPZGufHi6SvIarOzZ_Hqhs0K1707Jlm8Nad1QR-mSS4dhXCAWyFuF7uyAA9TrsmKQHIUPXQH3ohsYNkJ-MJwm168NoHL0_Bj2j00JLENHX1oK0iUQLFy2RasyOO6-ChpeYo4GCPxbXkXRNMst9RdOwswtqZKS9lKa4mSrV8_-rlb4exerAjDg2YPPoMSsXEZEZt1BmtnA_xEk2Ba9FhOw6p8n2zakljygABYj__RQ7pwvQZL9AQdpzrDu4eiYkl538d02K0It_d39qaUF-MQVNIqUv40OTI17kDAUhq9MFcYquHywFRcBzS2h0L5siHwieTqTaCPk9LEJwen2JlDWeXovmqX-bxuByh1TNemfkHKSG4lDhIW8Jg2wcilnNEuvvMRmVEAPDen8IaOiP3-S3gjXPv2wqrpG_HD4-XxjugEB0lTmtEn-tA-8jBTTG__H4kUjAv8gX94FW4QYmA9x-xKJwb8mVI_f9xTUMgmx7OsBXoGY1ddAmKfNA5dN4wtTYwKUIoj_VQ9LpXK86DNVlIuT-OaRE_wjLPxnUc0aTXGUUUQJNhmzLRa6xLeyw1A==","id":"rs_0c750dfa299f673c016980906c83288193a268c0d2c594d1ed","format":"openai-responses-v1","index":0}],"tool_calls":[{"id":"call_Rpqo15PMdWRph6Je9FbyRkrP","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence, Italy\"}"}}],"provider_metadata":{"openai":{"responseId":"resp_0c750dfa299f673c016980906c2e748193aacbf2a1a14f5495","serviceTier":"default"},"gateway":{"routing":{"originalModelId":"openai/gpt-5","resolvedProvider":"openai","resolvedProviderApiModelId":"gpt-5-2025-08-07","internalResolvedModelId":"openai:gpt-5-2025-08-07","fallbacksAvailable":["azure"],"internalReasoning":"Selected openai as preferred provider for gpt-5. 1 fallback(s) available: azure","planningReasoning":"System credentials planned for: openai, azure. Total execution order: openai(system) ā azure(system)","canonicalSlug":"openai/gpt-5","finalProvider":"openai","attempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":4677952.648505,"endTime":4679832.007624,"statusCode":200,"providerResponseId":"resp_0c750dfa299f673c016980906c2e748193aacbf2a1a14f5495"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"openai/gpt-5","canonicalSlug":"openai/gpt-5","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.00185875","marketCost":"0.00185875","generationId":"gen_01KGF389FA00FX9W76TJBD2FY0","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":63,"completion_tokens":114,"total_tokens":177,"cost":0.00185875,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":64,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.00185875},"system_fingerprint":"fp_4kn76nn85u","generationId":"gen_01KGF389FA00FX9W76TJBD2FY0"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.189340917s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2326
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_Rpqo15PMdWRph6Je9FbyRkrP","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"data":"gAAAAABpgJBt9rDWBVUu57Qp4eDPgvhNl_yejTP7GQIvS9aR9c0rc2udBHMKWf6Lov1QwiEeQbCc8LROQ_SbUEvfyEl-9PofdGalnrJON5sqNjhFmugyAnTzQwIbCLzHhViPQYcKTeDxYUNkLO-WUzh9UcgCE3H9-JaGFMFgvpEtK2izjoSXQAfcM4N4TpIjSZVLKCARs9L3jzHHdIMx1God2c7H0MErV3MDZ_7J_xlIDaVOQPKOOMzVO6EjBEWH9TQn_C3f2h5bm6YphGwIfcI7TxOmQVmf7NV0r9e5Tl0v2NQ6L5alFvBllJiKLOsmO6jShYoPT_i119sexG8bSw0w8qqlOvJJxA3nSmKgimH9TJXIynwqntgKw2sf3TUov2ZcXBXuuWEvwwuzvJZ-IblbQ4tp3voRndpGGLL5RaUAnVJxsawXAC7ghykRDhuqBywJVrc0HuNZKsl0qLjEi22IYXAhdbVerM84pD1IMgA-9XbzPryB6R6vvwk6UBQH7H35sSIywXRK0pWMJftKwUIfh87K8iPyt2sdvdxFgeCv1zygTwsvRNIyxrdLznmOlPPEmgeapkBzXMnpnhkIDRkm0q1owi849hYpArAr5dP9KonpVSkJEx_hO4Nu125WOtKG6kt59lWzVy5ntGaQbQx0Y9Ekg-YrVAt0MRBDTHbyYFvg01tRDT5qX7RTjVrxcnBJaS4jiHsE3ThGQCvlyUKDLrBD891lSuLZHJ-b_WDXiAZW63-INaU6dm7rkw0-kCCg6f02WEiTbwrUI3la4iJ_OHvO5dX8HMzO566TT_VPay9vmSAzBcO9vYyJHqAahlce6fc8HSC6yM4FmArFa7fAI24qzACBtcwPZGufHi6SvIarOzZ_Hqhs0K1707Jlm8Nad1QR-mSS4dhXCAWyFuF7uyAA9TrsmKQHIUPXQH3ohsYNkJ-MJwm168NoHL0_Bj2j00JLENHX1oK0iUQLFy2RasyOO6-ChpeYo4GCPxbXkXRNMst9RdOwswtqZKS9lKa4mSrV8_-rlb4exerAjDg2YPPoMSsXEZEZt1BmtnA_xEk2Ba9FhOw6p8n2zakljygABYj__RQ7pwvQZL9AQdpzrDu4eiYkl538d02K0It_d39qaUF-MQVNIqUv40OTI17kDAUhq9MFcYquHywFRcBzS2h0L5siHwieTqTaCPk9LEJwen2JlDWeXovmqX-bxuByh1TNemfkHKSG4lDhIW8Jg2wcilnNEuvvMRmVEAPDen8IaOiP3-S3gjXPv2wqrpG_HD4-XxjugEB0lTmtEn-tA-8jBTTG__H4kUjAv8gX94FW4QYmA9x-xKJwb8mVI_f9xTUMgmx7OsBXoGY1ddAmKfNA5dN4wtTYwKUIoj_VQ9LpXK86DNVlIuT-OaRE_wjLPxnUc0aTXGUUUQJNhmzLRa6xLeyw1A==","format":"openai-responses-v1","id":"rs_0c750dfa299f673c016980906c83288193a268c0d2c594d1ed","index":0,"type":"reasoning.encrypted"}]},{"content":"40 C","tool_call_id":"call_Rpqo15PMdWRph6Je9FbyRkrP","role":"tool"}],"model":"openai/gpt-5","max_completion_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF38BGEDFPFYA0YSVGK53PZ","object":"chat.completion","created":1770033266,"model":"openai/gpt-5","choices":[{"index":0,"message":{"role":"assistant","content":"The current temperature in Florence, Italy is 40°C (104°F). Would you like a forecast or more details?","reasoning_details":[{"type":"reasoning.encrypted","data":"gAAAAABpgJBy04wiPgHZlcnRtMeJdCXiXkMzEOjA4bYMCrCHqVuCdI7vEDq8PlukdtI96JyxomTXvXxRPCIzKJdzHSXR3OLLYvNzwfNDgNQ1dW4bvh69vQpp54zP4Dhs57GgfsfZAB7q9RB0Kg-6eJD86w2NsGfTIO2ITYeN-_Y5Bqeg8rOb4V9XK1pf-bLaeZsL4uBfvriH8M_uL5nEyaaZupiXTiZfv0A6Lb-lMWH9SS0PPy5LsSx0H_w-4OR8G6J2isU7-bG12BGklNspMvMmtj5JWmZbgbb-JHvR_NO7p--3Q6QCQzg088E_Uh1lQTqvnX3AffKuPJNgxVaiivOQwZXXLEG0NYULjeB20PNsMBVTi_OF4frTljlCvvTzecAd9iaeIECwDBEJDEgqTQefE0linoyLBeey8kD6DIweziBNn8ezoWU7ACiWCqz8FtB0smGue1W949AEmHfRizTjaqEbVpUiW3CA4aVp3eNZiu1XbE3b514H7XMG-6SBBohs0YfPdlTIez7To3Ptzv2x0t7KPiPZi7uDYTscYS1AWdTeB7LJRoLy3mO74Jmq0w0ZnSF3U2zu7-cHkyk6_x1R66bH8uLTtuQRzmyZtef-7T8QGt8k_belGqnRr9o9rdvLp80rwEjjwwPK9lIcR_mA1XDZZHEqoNWOQKINWxwwrjypgRDwSxs_FI3zi-OviKBsFe8YJTn3sJx1ppVkoBU-czhIfpfeF1wqjgGxIIcGGXm8wVXGqWG1Nm-AZwNLxnf34CfhcBddIL4lbPwMa39aaGYGU2qc9Qj8egNg7Bzk0wysMxC4ttsQSpcGM1CXVuyYY9nKiNybsbFQGSB6S32blf05IVD6J1WRqRWlQjJ-doPxmRMqKkXVWOuLN6jHpjAVhtQt2a2jMOvzkuj1bkmrxwLZ6HVKdFEgTN1tVRZ8URSvN3KAQxkOmLr0qPFjqEocjCM8CCTvWSZPbEGTKmHGZBqWFRkOTTC9r0XL_NmeDPZ8x9IfRRTjHg4lJpMixQyrTpgqUHJ_YWgo_jQGFWGntrj8YVfTaOjJmDXigBb2eUr22Tu72U8sBFURrBFDvXQvrL_gbgP4KifJ9ablHQ5M7k2W-I1wD9SgW77LZYYtsDdr_bv1tLIv9zn7tien8eAv1RQN4cICC8yJSnd_8RpzVnpVg6ZyDHOMRL9fU5URSQvtl0ld8c-Hu46NRTR_Ua6b1bIrCVswrbFF0j1tvEA3UBKnuN92LNavwOlu_N7AAPy0tmSvTk0bxfuus3AHDMAEzeHbQBH2OclogxZcfnrm1dXk3ee24hksoxJjfMVTzRBaVPssUCN_ZLzu1T6GwQ4YCdMl2QKX1KWz9ONt6zDNjvkhbZKGYod9E0anXx91NMzhIwou15N1USmduEuklufFN6adsQDWyJ_dK-mS1tlVI9GcDVNnbRUbHvtNui2qwtCzLGxyY82blpFO6dZRjpzY1YRtqo9QA-3MXT1J1mwPmnP2nQh8x5DQPZ-wxs3TcC0DuPVhu-pWmc1RyUtrri3vUy6evRKkezMqybI2zSibyq96ORSAQfB6jZmkyGCNj_w3oCEgYpFJRpPdK42z7SydPItcHGyTbFIE72QqD5lbMA37vCx6iCN38tTUNRYhmeXcKAot9wN5TZ_zNs8TY6BbW1PaIGnPumEudzJCFZhlwPkN6_93U57l23S0chlyA34JN7JMrjI3gVyI0WYFY6IrgQzknsiwpmMAqi9_RQaY6wgVBHadORhAufCHOvq-Qgrcbzpgppuc6zWp7qpc-PACaXLdG2HBvD_whxNmKjaW8b4sUu0IEhHv4esQ4Cxdurb6PAsPPRyUqAyfYX3uYKePFCSGe_Gv6Zss6Lbd5hp0GBvLoVdCxa_81e0EH62Oi5OzbiUpWGY1717a9l6SepkbpbyYnllAMuNGI8whTOBJrDXNR85-lNMSEfVIg6Pjw7Imle0jFkZX1ASfHLXCta9elSYiw7pYIzW67aO3DUacyqKYUxEqO2kVWtcllcO1-_s3rJzKAM4_Qp7A80_0B9X1CfkEKWKLpdJTjfeAiMKtqOTEs0IXngkbaxppW6KdxBsj5bhGCTAXhq_yXeCkBei_aVteFzK2BO1vvLlUhMysIzxs8CLs1YLdAA6vO2dEznTujNxz9Rc=","id":"rs_0c750dfa299f673c016980906e9f1c8193a6477099ec37fe1e","format":"openai-responses-v1","index":0}],"provider_metadata":{"openai":{"responseId":"resp_0c750dfa299f673c016980906e3c00819389d21d48153004b1","serviceTier":"default"},"gateway":{"routing":{"originalModelId":"openai/gpt-5","resolvedProvider":"openai","resolvedProviderApiModelId":"gpt-5-2025-08-07","internalResolvedModelId":"openai:gpt-5-2025-08-07","fallbacksAvailable":["azure"],"internalReasoning":"Selected openai as preferred provider for gpt-5. 1 fallback(s) available: azure","planningReasoning":"System credentials planned for: openai, azure. Total execution order: openai(system) ā azure(system)","canonicalSlug":"openai/gpt-5","finalProvider":"openai","attempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":1368084.873343,"endTime":1372326.249053,"statusCode":200,"providerResponseId":"resp_0c750dfa299f673c016980906e3c00819389d21d48153004b1"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"openai/gpt-5","canonicalSlug":"openai/gpt-5","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.0045725","marketCost":"0.0045725","generationId":"gen_01KGF38BGEDFPFYA0YSVGK53PZ","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":186,"completion_tokens":242,"total_tokens":428,"cost":0.0045725,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":192,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.0045725},"system_fingerprint":"fp_4lohj8xzuj","generationId":"gen_01KGF38BGEDFPFYA0YSVGK53PZ"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 4.324064375s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/tool_streaming.yaml
new file mode 100644
index 000000000..1b7e34bb5
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommon/gpt-5/tool_streaming.yaml
@@ -0,0 +1,119 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 519
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"openai/gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF38FRCNWV564Q8599HRRAW","object":"chat.completion.chunk","created":1770033266,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_147br1mgel"}
+
+ data: {"id":"gen_01KGF38FRCNWV564Q8599HRRAW","object":"chat.completion.chunk","created":1770033266,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning_details":[{"type":"reasoning.encrypted","data":"gAAAAABpgJByBdy9g4TuHPa7DgknLNhMVPGBacw6RSFlD86GixiOuj40lDELdX_Q4KpFNDGcs2gWwNHn1H7rIRCRF7wxROP_609IYjQjHTHB5_0by_qtfPjubqMYZbBfLC9pD5LMt3wpLFWxvAkk-PckiEuLpg1NcdorEuBFlJgwEOKUgO51ZGJbVvpwBsqrcv2xrMSS1jp8NIwy70pS8GS8Chq74_U4FIB26Mpvi_67J_zuXCqiIL9YklAwao0gdOCNGRyKoioVhcOMpS85FvFB8Sg5HstfrBPyKxqNx65gAT9PkL-YS4Fnu403tFbWXIQEZK-oC4oMqpjZKSllX6lYRQdEMZ8TdGLX1FuzXT8apGuqpEcKKeSlUaF_4T5UzLszir9DvQRwapFdiyBrZaR1lWGvkfB6695EQLjgF0cM0qiyBmQ2QHcfEPWIvB4s_kvbE7VxZbZwzAQJwtevqnU1V4ZbG8uh60jClbHOLOiK-Ty5xntV9Pai9ISDeUpmVlfv60cvjRGyxYOIR6fu3uwZSZrje-OfnYUmC9_s6aDhbrNe-IEvhnlhBSbemJwolxE6buieN4kdjZ2xlqDFY2mk8nLx8tF6ZiP4IROD0_ZRz-k7k9cGEncfvTFtkITcfum_0_M-v94SuvRSGMjW6QjMun8UgSiMxBoAlftJWtZxlVBLiCao2fNlbaXdKEUuFS7CG8lfRUybrwSZiOgIPp7mLx05blU6MApN1vE6iSEHuNncRTKryb58XchOLOJRld1OH1NjFsE5_cczhvguSKkJb8uqdl_kOgtQea4XNRWlirogKKKiKdbpOH2F2wVwrYGXCdqGQBE5","id":"rs_02e57b3492270d950169809072df2c81958978be9de09c65c6","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_147br1mgel"}
+
+ data: {"id":"gen_01KGF38FRCNWV564Q8599HRRAW","object":"chat.completion.chunk","created":1770033266,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_kjY7wC8Gbmob78vc6x7vvFRl","type":"function","function":{"name":"weather","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_147br1mgel"}
+
+ data: {"id":"gen_01KGF38FRCNWV564Q8599HRRAW","object":"chat.completion.chunk","created":1770033266,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_147br1mgel"}
+
+ data: {"id":"gen_01KGF38FRCNWV564Q8599HRRAW","object":"chat.completion.chunk","created":1770033266,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"location"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_147br1mgel"}
+
+ data: {"id":"gen_01KGF38FRCNWV564Q8599HRRAW","object":"chat.completion.chunk","created":1770033266,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_147br1mgel"}
+
+ data: {"id":"gen_01KGF38FRCNWV564Q8599HRRAW","object":"chat.completion.chunk","created":1770033266,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Flor"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_147br1mgel"}
+
+ data: {"id":"gen_01KGF38FRCNWV564Q8599HRRAW","object":"chat.completion.chunk","created":1770033266,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"ence"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_147br1mgel"}
+
+ data: {"id":"gen_01KGF38FRCNWV564Q8599HRRAW","object":"chat.completion.chunk","created":1770033266,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":","}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_147br1mgel"}
+
+ data: {"id":"gen_01KGF38FRCNWV564Q8599HRRAW","object":"chat.completion.chunk","created":1770033266,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" Italy"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_147br1mgel"}
+
+ data: {"id":"gen_01KGF38FRCNWV564Q8599HRRAW","object":"chat.completion.chunk","created":1770033266,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_147br1mgel"}
+
+ data: {"id":"gen_01KGF38FRCNWV564Q8599HRRAW","object":"chat.completion.chunk","created":1770033266,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"provider_metadata":{"openai":{"responseId":"resp_02e57b3492270d9501698090728f488195b501a282cdac33a5","serviceTier":"default"},"gateway":{"routing":{"originalModelId":"openai/gpt-5","resolvedProvider":"openai","resolvedProviderApiModelId":"gpt-5-2025-08-07","internalResolvedModelId":"openai:gpt-5-2025-08-07","fallbacksAvailable":["azure"],"internalReasoning":"Selected openai as preferred provider for gpt-5. 1 fallback(s) available: azure","planningReasoning":"System credentials planned for: openai, azure. Total execution order: openai(system) ā azure(system)","canonicalSlug":"openai/gpt-5","finalProvider":"openai","attempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":3180361.719299,"endTime":3180600.837456,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"openai/gpt-5","canonicalSlug":"openai/gpt-5","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":3180361.719299,"endTime":3180600.837456,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.00191875","marketCost":"0.00191875","generationId":"gen_01KGF38FRCNWV564Q8599HRRAW","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":63,"completion_tokens":120,"total_tokens":183,"cost":0.00191875,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":64,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.00191875},"system_fingerprint":"fp_147br1mgel","generationId":"gen_01KGF38FRCNWV564Q8599HRRAW"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 376.16525ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1780
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"call_kjY7wC8Gbmob78vc6x7vvFRl","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"data":"gAAAAABpgJByBdy9g4TuHPa7DgknLNhMVPGBacw6RSFlD86GixiOuj40lDELdX_Q4KpFNDGcs2gWwNHn1H7rIRCRF7wxROP_609IYjQjHTHB5_0by_qtfPjubqMYZbBfLC9pD5LMt3wpLFWxvAkk-PckiEuLpg1NcdorEuBFlJgwEOKUgO51ZGJbVvpwBsqrcv2xrMSS1jp8NIwy70pS8GS8Chq74_U4FIB26Mpvi_67J_zuXCqiIL9YklAwao0gdOCNGRyKoioVhcOMpS85FvFB8Sg5HstfrBPyKxqNx65gAT9PkL-YS4Fnu403tFbWXIQEZK-oC4oMqpjZKSllX6lYRQdEMZ8TdGLX1FuzXT8apGuqpEcKKeSlUaF_4T5UzLszir9DvQRwapFdiyBrZaR1lWGvkfB6695EQLjgF0cM0qiyBmQ2QHcfEPWIvB4s_kvbE7VxZbZwzAQJwtevqnU1V4ZbG8uh60jClbHOLOiK-Ty5xntV9Pai9ISDeUpmVlfv60cvjRGyxYOIR6fu3uwZSZrje-OfnYUmC9_s6aDhbrNe-IEvhnlhBSbemJwolxE6buieN4kdjZ2xlqDFY2mk8nLx8tF6ZiP4IROD0_ZRz-k7k9cGEncfvTFtkITcfum_0_M-v94SuvRSGMjW6QjMun8UgSiMxBoAlftJWtZxlVBLiCao2fNlbaXdKEUuFS7CG8lfRUybrwSZiOgIPp7mLx05blU6MApN1vE6iSEHuNncRTKryb58XchOLOJRld1OH1NjFsE5_cczhvguSKkJb8uqdl_kOgtQea4XNRWlirogKKKiKdbpOH2F2wVwrYGXCdqGQBE5","format":"openai-responses-v1","id":"rs_02e57b3492270d950169809072df2c81958978be9de09c65c6","index":0,"type":"reasoning.encrypted"}]},{"content":"40 C","tool_call_id":"call_kjY7wC8Gbmob78vc6x7vvFRl","role":"tool"}],"model":"openai/gpt-5","max_completion_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF38HQ7R9XH4N23YXVZ2V51","object":"chat.completion.chunk","created":1770033268,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_9trj17vyed"}
+
+ data: {"id":"gen_01KGF38HQ7R9XH4N23YXVZ2V51","object":"chat.completion.chunk","created":1770033268,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_9trj17vyed"}
+
+ data: {"id":"gen_01KGF38HQ7R9XH4N23YXVZ2V51","object":"chat.completion.chunk","created":1770033268,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" current"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_9trj17vyed"}
+
+ data: {"id":"gen_01KGF38HQ7R9XH4N23YXVZ2V51","object":"chat.completion.chunk","created":1770033268,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_9trj17vyed"}
+
+ data: {"id":"gen_01KGF38HQ7R9XH4N23YXVZ2V51","object":"chat.completion.chunk","created":1770033268,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_9trj17vyed"}
+
+ data: {"id":"gen_01KGF38HQ7R9XH4N23YXVZ2V51","object":"chat.completion.chunk","created":1770033268,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" Florence"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_9trj17vyed"}
+
+ data: {"id":"gen_01KGF38HQ7R9XH4N23YXVZ2V51","object":"chat.completion.chunk","created":1770033268,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_9trj17vyed"}
+
+ data: {"id":"gen_01KGF38HQ7R9XH4N23YXVZ2V51","object":"chat.completion.chunk","created":1770033268,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" Italy"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_9trj17vyed"}
+
+ data: {"id":"gen_01KGF38HQ7R9XH4N23YXVZ2V51","object":"chat.completion.chunk","created":1770033268,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_9trj17vyed"}
+
+ data: {"id":"gen_01KGF38HQ7R9XH4N23YXVZ2V51","object":"chat.completion.chunk","created":1770033268,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" about"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_9trj17vyed"}
+
+ data: {"id":"gen_01KGF38HQ7R9XH4N23YXVZ2V51","object":"chat.completion.chunk","created":1770033268,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_9trj17vyed"}
+
+ data: {"id":"gen_01KGF38HQ7R9XH4N23YXVZ2V51","object":"chat.completion.chunk","created":1770033268,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"40"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_9trj17vyed"}
+
+ data: {"id":"gen_01KGF38HQ7R9XH4N23YXVZ2V51","object":"chat.completion.chunk","created":1770033268,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"°C"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_9trj17vyed"}
+
+ data: {"id":"gen_01KGF38HQ7R9XH4N23YXVZ2V51","object":"chat.completion.chunk","created":1770033268,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_9trj17vyed"}
+
+ data: {"id":"gen_01KGF38HQ7R9XH4N23YXVZ2V51","object":"chat.completion.chunk","created":1770033268,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"provider_metadata":{"openai":{"responseId":"resp_02e57b3492270d950169809074a41c8195b28990630eb61d38","serviceTier":"default"},"gateway":{"routing":{"originalModelId":"openai/gpt-5","resolvedProvider":"openai","resolvedProviderApiModelId":"gpt-5-2025-08-07","internalResolvedModelId":"openai:gpt-5-2025-08-07","fallbacksAvailable":["azure"],"internalReasoning":"Selected openai as preferred provider for gpt-5. 1 fallback(s) available: azure","planningReasoning":"System credentials planned for: openai, azure. Total execution order: openai(system) ā azure(system)","canonicalSlug":"openai/gpt-5","finalProvider":"openai","attempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":3182379.990316,"endTime":3182610.529457,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"openai/gpt-5","canonicalSlug":"openai/gpt-5","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":3182379.990316,"endTime":3182610.529457,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.00029125","marketCost":"0.00029125","generationId":"gen_01KGF38HQ7R9XH4N23YXVZ2V51","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":97,"completion_tokens":17,"total_tokens":114,"cost":0.00029125,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.00029125},"system_fingerprint":"fp_9trj17vyed","generationId":"gen_01KGF38HQ7R9XH4N23YXVZ2V51"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 378.669292ms
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/multi_tool.yaml b/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/multi_tool.yaml
new file mode 100644
index 000000000..fa6b1b6d6
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/multi_tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 904
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system","cache_control":{"type":"ephemeral"}},{"content":"Add and multiply the number 2 and 3","role":"user","cache_control":{"type":"ephemeral"}}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF3AEN63MVZD10V5VWY1NFK","object":"chat.completion","created":1770033333,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"message":{"role":"assistant","content":null,"tool_calls":[{"id":"toolu_018Bqrp5E4LTkWWKFAWjJcPw","type":"function","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"}},{"id":"toolu_01ModQEwNzE9utyENTnUKDzE","type":"function","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"}}],"provider_metadata":{"anthropic":{"usage":{"input_tokens":507,"output_tokens":137,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":7080018.781706,"endTime":7082515.69486,"statusCode":200,"providerResponseId":"msg_0198xyvGQtALbxVJ6en1oy92"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.003576","marketCost":"0.003576","generationId":"gen_01KGF3AEN63MVZD10V5VWY1NFK","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":507,"completion_tokens":137,"total_tokens":644,"cost":0.003576,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.003576},"system_fingerprint":"fp_hbuq90twge","generationId":"gen_01KGF3AEN63MVZD10V5VWY1NFK"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.724311375s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1333
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system","cache_control":{"type":"ephemeral"}},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"toolu_018Bqrp5E4LTkWWKFAWjJcPw","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"toolu_01ModQEwNzE9utyENTnUKDzE","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function","cache_control":{"type":"ephemeral"}}],"role":"assistant"},{"content":"5","tool_call_id":"toolu_018Bqrp5E4LTkWWKFAWjJcPw","role":"tool"},{"content":"6","tool_call_id":"toolu_01ModQEwNzE9utyENTnUKDzE","role":"tool"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF3AH9QQJ48CR5J8VYYZN30","object":"chat.completion","created":1770033335,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"message":{"role":"assistant","content":"I''ve performed both operations with the numbers 2 and 3:\n- Addition: 2 + 3 = 5\n- Multiplication: 2 Ć 3 = 6","provider_metadata":{"anthropic":{"usage":{"input_tokens":688,"output_tokens":47,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":1440501.815188,"endTime":1442379.185058,"statusCode":200,"providerResponseId":"msg_01HoW3wJwr4Hqen1m7PJHcEL"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.002769","marketCost":"0.002769","generationId":"gen_01KGF3AH9QQJ48CR5J8VYYZN30","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":688,"completion_tokens":47,"total_tokens":735,"cost":0.002769,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002769},"system_fingerprint":"fp_yb4k07q27e","generationId":"gen_01KGF3AH9QQJ48CR5J8VYYZN30"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.006164709s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/multi_tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/multi_tool_streaming.yaml
new file mode 100644
index 000000000..53b09c8f2
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/multi_tool_streaming.yaml
@@ -0,0 +1,119 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 941
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system","cache_control":{"type":"ephemeral"}},{"content":"Add and multiply the number 2 and 3","role":"user","cache_control":{"type":"ephemeral"}}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"I"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"'ll"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" ad"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"d an"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"d multiply the"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" numbers 2 and 3 "},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"for you."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"toolu_01EbUPM9AHLKandFdpD3hR2d","type":"function","function":{"name":"add","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"a\": 2"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":", \"b\""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":": 3}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"toolu_01WJxb3WgmL33DJCq2hw4DFL","type":"function","function":{"name":"multiply","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"a\": "}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"2"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":", "}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"\"b\""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":": 3}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kk4h3svyf"}
+
+ data: {"id":"gen_01KGF3AK848QW52MG188A9XZRA","object":"chat.completion.chunk","created":1770033336,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"provider_metadata":{"anthropic":{"usage":{"input_tokens":502,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":137,"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":4753514.35299,"endTime":4754858.992657,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":4753514.35299,"endTime":4754858.992657,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.003561","marketCost":"0.003561","generationId":"gen_01KGF3AK848QW52MG188A9XZRA","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":502,"completion_tokens":137,"total_tokens":639,"cost":0.003561,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.003561},"system_fingerprint":"fp_kk4h3svyf","generationId":"gen_01KGF3AK848QW52MG188A9XZRA"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.471487583s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1439
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system","cache_control":{"type":"ephemeral"}},{"content":"Add and multiply the number 2 and 3","role":"user"},{"content":"I''ll add and multiply the numbers 2 and 3 for you.","tool_calls":[{"id":"toolu_01EbUPM9AHLKandFdpD3hR2d","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"toolu_01WJxb3WgmL33DJCq2hw4DFL","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function","cache_control":{"type":"ephemeral"}}],"role":"assistant"},{"content":"5","tool_call_id":"toolu_01EbUPM9AHLKandFdpD3hR2d","role":"tool"},{"content":"6","tool_call_id":"toolu_01WJxb3WgmL33DJCq2hw4DFL","role":"tool"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF3ANVSZB8AH86G2J0K92JN","object":"chat.completion.chunk","created":1770033339,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_jv4rc3pqm1"}
+
+ data: {"id":"gen_01KGF3ANVSZB8AH86G2J0K92JN","object":"chat.completion.chunk","created":1770033339,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_jv4rc3pqm1"}
+
+ data: {"id":"gen_01KGF3ANVSZB8AH86G2J0K92JN","object":"chat.completion.chunk","created":1770033339,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" results"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_jv4rc3pqm1"}
+
+ data: {"id":"gen_01KGF3ANVSZB8AH86G2J0K92JN","object":"chat.completion.chunk","created":1770033339,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" are:\n- "},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_jv4rc3pqm1"}
+
+ data: {"id":"gen_01KGF3ANVSZB8AH86G2J0K92JN","object":"chat.completion.chunk","created":1770033339,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"2 + 3 = "},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_jv4rc3pqm1"}
+
+ data: {"id":"gen_01KGF3ANVSZB8AH86G2J0K92JN","object":"chat.completion.chunk","created":1770033339,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"5\n- 2 Ć "},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_jv4rc3pqm1"}
+
+ data: {"id":"gen_01KGF3ANVSZB8AH86G2J0K92JN","object":"chat.completion.chunk","created":1770033339,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"3 = 6"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_jv4rc3pqm1"}
+
+ data: {"id":"gen_01KGF3ANVSZB8AH86G2J0K92JN","object":"chat.completion.chunk","created":1770033339,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"provider_metadata":{"anthropic":{"usage":{"input_tokens":700,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":31,"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":1445140.487939,"endTime":1446016.149192,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":1445140.487939,"endTime":1446016.149192,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.002565","marketCost":"0.002565","generationId":"gen_01KGF3ANVSZB8AH86G2J0K92JN","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":700,"completion_tokens":31,"total_tokens":731,"cost":0.002565,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002565},"system_fingerprint":"fp_jv4rc3pqm1","generationId":"gen_01KGF3ANVSZB8AH86G2J0K92JN"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.063098791s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/simple.yaml b/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/simple.yaml
new file mode 100644
index 000000000..664b864eb
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/simple.yaml
@@ -0,0 +1,33 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 249
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system","cache_control":{"type":"ephemeral"}},{"content":"Say hi in Portuguese","role":"user","cache_control":{"type":"ephemeral"}}],"model":"anthropic/claude-sonnet-4","max_tokens":4000}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF3A0GNP7F130T7D4SZFNFG","object":"chat.completion","created":1770033318,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"message":{"role":"assistant","content":"OlĆ”! (Oh-LAH)\n\nThis is the most common way to say \"hi\" in Portuguese. You can also use \"Oi!\" (OH-ee) for a more casual greeting.","provider_metadata":{"anthropic":{"usage":{"input_tokens":16,"output_tokens":48,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":305884.462307,"endTime":307858.655195,"statusCode":200,"providerResponseId":"msg_01NUekGRWWJS2rvj8HY222rZ"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.000768","marketCost":"0.000768","generationId":"gen_01KGF3A0GNP7F130T7D4SZFNFG","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":16,"completion_tokens":48,"total_tokens":64,"cost":0.000768,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.000768},"system_fingerprint":"fp_qvkh98zees","generationId":"gen_01KGF3A0GNP7F130T7D4SZFNFG"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.145596209s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/simple_streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/simple_streaming.yaml
new file mode 100644
index 000000000..219e897ef
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/simple_streaming.yaml
@@ -0,0 +1,60 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 303
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system","cache_control":{"type":"ephemeral"}},{"content":"Say hi in Portuguese","role":"user","cache_control":{"type":"ephemeral"}}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF3A2KGQFE5BW4K7TRSZ9DF","object":"chat.completion.chunk","created":1770033319,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_c0bnftwhqr"}
+
+ data: {"id":"gen_01KGF3A2KGQFE5BW4K7TRSZ9DF","object":"chat.completion.chunk","created":1770033319,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"OlĆ”! "},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_c0bnftwhqr"}
+
+ data: {"id":"gen_01KGF3A2KGQFE5BW4K7TRSZ9DF","object":"chat.completion.chunk","created":1770033319,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"\n\n("},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_c0bnftwhqr"}
+
+ data: {"id":"gen_01KGF3A2KGQFE5BW4K7TRSZ9DF","object":"chat.completion.chunk","created":1770033319,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"That"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_c0bnftwhqr"}
+
+ data: {"id":"gen_01KGF3A2KGQFE5BW4K7TRSZ9DF","object":"chat.completion.chunk","created":1770033319,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"'s \""},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_c0bnftwhqr"}
+
+ data: {"id":"gen_01KGF3A2KGQFE5BW4K7TRSZ9DF","object":"chat.completion.chunk","created":1770033319,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"hello"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_c0bnftwhqr"}
+
+ data: {"id":"gen_01KGF3A2KGQFE5BW4K7TRSZ9DF","object":"chat.completion.chunk","created":1770033319,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"\" in Portuguese -"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_c0bnftwhqr"}
+
+ data: {"id":"gen_01KGF3A2KGQFE5BW4K7TRSZ9DF","object":"chat.completion.chunk","created":1770033319,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_c0bnftwhqr"}
+
+ data: {"id":"gen_01KGF3A2KGQFE5BW4K7TRSZ9DF","object":"chat.completion.chunk","created":1770033319,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" friendly"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_c0bnftwhqr"}
+
+ data: {"id":"gen_01KGF3A2KGQFE5BW4K7TRSZ9DF","object":"chat.completion.chunk","created":1770033319,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" way"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_c0bnftwhqr"}
+
+ data: {"id":"gen_01KGF3A2KGQFE5BW4K7TRSZ9DF","object":"chat.completion.chunk","created":1770033319,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" to say hi"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_c0bnftwhqr"}
+
+ data: {"id":"gen_01KGF3A2KGQFE5BW4K7TRSZ9DF","object":"chat.completion.chunk","created":1770033319,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"!)"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_c0bnftwhqr"}
+
+ data: {"id":"gen_01KGF3A2KGQFE5BW4K7TRSZ9DF","object":"chat.completion.chunk","created":1770033319,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"provider_metadata":{"anthropic":{"usage":{"input_tokens":16,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":25,"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":1425425.670751,"endTime":1426422.314773,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":1425425.670751,"endTime":1426422.314773,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.000423","marketCost":"0.000423","generationId":"gen_01KGF3A2KGQFE5BW4K7TRSZ9DF","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":16,"completion_tokens":25,"total_tokens":41,"cost":0.000423,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.000423},"system_fingerprint":"fp_c0bnftwhqr","generationId":"gen_01KGF3A2KGQFE5BW4K7TRSZ9DF"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.097552958s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/tool.yaml b/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/tool.yaml
new file mode 100644
index 000000000..cfd728d52
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/tool.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 541
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system","cache_control":{"type":"ephemeral"}},{"content":"What''s the weather in Florence,Italy?","role":"user","cache_control":{"type":"ephemeral"}}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF3A4CMTZP7AVTFGEHA9VZ3","object":"chat.completion","created":1770033322,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"message":{"role":"assistant","content":null,"tool_calls":[{"id":"toolu_0199hSTV5K6aGu7K5MRpvNEk","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence,Italy\"}"}}],"provider_metadata":{"anthropic":{"usage":{"input_tokens":394,"output_tokens":68,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":7069466.244378,"endTime":7071689.075105,"statusCode":200,"providerResponseId":"msg_01CtwtuZqqwryJAuJDdMoG65"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.002202","marketCost":"0.002202","generationId":"gen_01KGF3A4CMTZP7AVTFGEHA9VZ3","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":394,"completion_tokens":68,"total_tokens":462,"cost":0.002202,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002202},"system_fingerprint":"fp_nd3kr99iaq","generationId":"gen_01KGF3A4CMTZP7AVTFGEHA9VZ3"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.395244583s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 794
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system","cache_control":{"type":"ephemeral"}},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"toolu_0199hSTV5K6aGu7K5MRpvNEk","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function","cache_control":{"type":"ephemeral"}}],"role":"assistant"},{"content":"40 C","tool_call_id":"toolu_0199hSTV5K6aGu7K5MRpvNEk","role":"tool"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}]}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF3A6QKNJNQRZ2JER4MQD46","object":"chat.completion","created":1770033325,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"message":{"role":"assistant","content":"The weather in Florence, Italy is currently 40°C (104°F). That''s quite hot! It''s a very warm day in Florence.","provider_metadata":{"anthropic":{"usage":{"input_tokens":463,"output_tokens":34,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":7072056.878135,"endTime":7074733.980106,"statusCode":200,"providerResponseId":"msg_01EYzxaa6Ayp7ACF78uvBrqV"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.001899","marketCost":"0.001899","generationId":"gen_01KGF3A6QKNJNQRZ2JER4MQD46","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":463,"completion_tokens":34,"total_tokens":497,"cost":0.001899,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.001899},"system_fingerprint":"fp_4i6565f6ii","generationId":"gen_01KGF3A6QKNJNQRZ2JER4MQD46"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.949003792s
diff --git a/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/tool_streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/tool_streaming.yaml
new file mode 100644
index 000000000..104f05bd5
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelCommonWithAnthropicCache/claude-sonnet-4/tool_streaming.yaml
@@ -0,0 +1,117 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 595
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system","cache_control":{"type":"ephemeral"}},{"content":"What''s the weather in Florence,Italy?","role":"user","cache_control":{"type":"ephemeral"}}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF3A9P5RW4MNWQD4RZQY7FA","object":"chat.completion.chunk","created":1770033327,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_afeigrmiv8"}
+
+ data: {"id":"gen_01KGF3A9P5RW4MNWQD4RZQY7FA","object":"chat.completion.chunk","created":1770033327,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"I'll get"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_afeigrmiv8"}
+
+ data: {"id":"gen_01KGF3A9P5RW4MNWQD4RZQY7FA","object":"chat.completion.chunk","created":1770033327,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" the weather information"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_afeigrmiv8"}
+
+ data: {"id":"gen_01KGF3A9P5RW4MNWQD4RZQY7FA","object":"chat.completion.chunk","created":1770033327,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" for Florence, Italy for you."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_afeigrmiv8"}
+
+ data: {"id":"gen_01KGF3A9P5RW4MNWQD4RZQY7FA","object":"chat.completion.chunk","created":1770033327,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"toolu_01NEeARJCxoJWc8F8yKkyTK2","type":"function","function":{"name":"weather","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_afeigrmiv8"}
+
+ data: {"id":"gen_01KGF3A9P5RW4MNWQD4RZQY7FA","object":"chat.completion.chunk","created":1770033327,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"l"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_afeigrmiv8"}
+
+ data: {"id":"gen_01KGF3A9P5RW4MNWQD4RZQY7FA","object":"chat.completion.chunk","created":1770033327,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"ocati"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_afeigrmiv8"}
+
+ data: {"id":"gen_01KGF3A9P5RW4MNWQD4RZQY7FA","object":"chat.completion.chunk","created":1770033327,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"on\": \"Flore"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_afeigrmiv8"}
+
+ data: {"id":"gen_01KGF3A9P5RW4MNWQD4RZQY7FA","object":"chat.completion.chunk","created":1770033327,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"nce,Italy\"}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_afeigrmiv8"}
+
+ data: {"id":"gen_01KGF3A9P5RW4MNWQD4RZQY7FA","object":"chat.completion.chunk","created":1770033327,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"provider_metadata":{"anthropic":{"usage":{"input_tokens":394,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":67,"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":7695608.34416,"endTime":7697403.6705,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":7695608.34416,"endTime":7697403.6705,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.002187","marketCost":"0.002187","generationId":"gen_01KGF3A9P5RW4MNWQD4RZQY7FA","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":394,"completion_tokens":67,"total_tokens":461,"cost":0.002187,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002187},"system_fingerprint":"fp_afeigrmiv8","generationId":"gen_01KGF3A9P5RW4MNWQD4RZQY7FA"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 2.320939125s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 923
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system","cache_control":{"type":"ephemeral"}},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"content":"I''ll get the weather information for Florence, Italy for you.","tool_calls":[{"id":"toolu_01NEeARJCxoJWc8F8yKkyTK2","function":{"arguments":"{\"location\": \"Florence,Italy\"}","name":"weather"},"type":"function","cache_control":{"type":"ephemeral"}}],"role":"assistant"},{"content":"40 C","tool_call_id":"toolu_01NEeARJCxoJWc8F8yKkyTK2","role":"tool"}],"model":"anthropic/claude-sonnet-4","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF3ACA8VVD000VSTT20BPP5","object":"chat.completion.chunk","created":1770033330,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_273kaqn10v"}
+
+ data: {"id":"gen_01KGF3ACA8VVD000VSTT20BPP5","object":"chat.completion.chunk","created":1770033330,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"The current"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_273kaqn10v"}
+
+ data: {"id":"gen_01KGF3ACA8VVD000VSTT20BPP5","object":"chat.completion.chunk","created":1770033330,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" weather in Florence, Italy is 40"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_273kaqn10v"}
+
+ data: {"id":"gen_01KGF3ACA8VVD000VSTT20BPP5","object":"chat.completion.chunk","created":1770033330,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"°C (104°F). That"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_273kaqn10v"}
+
+ data: {"id":"gen_01KGF3ACA8VVD000VSTT20BPP5","object":"chat.completion.chunk","created":1770033330,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"'s quite"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_273kaqn10v"}
+
+ data: {"id":"gen_01KGF3ACA8VVD000VSTT20BPP5","object":"chat.completion.chunk","created":1770033330,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" hot"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_273kaqn10v"}
+
+ data: {"id":"gen_01KGF3ACA8VVD000VSTT20BPP5","object":"chat.completion.chunk","created":1770033330,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"! If"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_273kaqn10v"}
+
+ data: {"id":"gen_01KGF3ACA8VVD000VSTT20BPP5","object":"chat.completion.chunk","created":1770033330,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" you're planning to visit or"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_273kaqn10v"}
+
+ data: {"id":"gen_01KGF3ACA8VVD000VSTT20BPP5","object":"chat.completion.chunk","created":1770033330,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" are currently"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_273kaqn10v"}
+
+ data: {"id":"gen_01KGF3ACA8VVD000VSTT20BPP5","object":"chat.completion.chunk","created":1770033330,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" there, make"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_273kaqn10v"}
+
+ data: {"id":"gen_01KGF3ACA8VVD000VSTT20BPP5","object":"chat.completion.chunk","created":1770033330,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" sure to"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_273kaqn10v"}
+
+ data: {"id":"gen_01KGF3ACA8VVD000VSTT20BPP5","object":"chat.completion.chunk","created":1770033330,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" stay"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_273kaqn10v"}
+
+ data: {"id":"gen_01KGF3ACA8VVD000VSTT20BPP5","object":"chat.completion.chunk","created":1770033330,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" hydrated and seek"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_273kaqn10v"}
+
+ data: {"id":"gen_01KGF3ACA8VVD000VSTT20BPP5","object":"chat.completion.chunk","created":1770033330,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" shade during the hottest parts of the"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_273kaqn10v"}
+
+ data: {"id":"gen_01KGF3ACA8VVD000VSTT20BPP5","object":"chat.completion.chunk","created":1770033330,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" day."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_273kaqn10v"}
+
+ data: {"id":"gen_01KGF3ACA8VVD000VSTT20BPP5","object":"chat.completion.chunk","created":1770033330,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"provider_metadata":{"anthropic":{"usage":{"input_tokens":476,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":54,"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":7697797.908831,"endTime":7699158.038376,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":7697797.908831,"endTime":7699158.038376,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.002238","marketCost":"0.002238","generationId":"gen_01KGF3ACA8VVD000VSTT20BPP5","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":476,"completion_tokens":54,"total_tokens":530,"cost":0.002238,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002238},"system_fingerprint":"fp_273kaqn10v","generationId":"gen_01KGF3ACA8VVD000VSTT20BPP5"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.463354875s
diff --git a/internal/fantasy/providertests/testdata/TestVercelThinking/claude-sonnet-4-sig/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelThinking/claude-sonnet-4-sig/thinking-streaming.yaml
new file mode 100644
index 000000000..cb7d1b4b1
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelThinking/claude-sonnet-4-sig/thinking-streaming.yaml
@@ -0,0 +1,137 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 533
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"anthropic/claude-sonnet-4","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"enabled":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":"The user is asking for","reasoning_details":[{"type":"reasoning.text","text":"The user is asking for","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" weather","reasoning_details":[{"type":"reasoning.text","text":" weather","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" information for Florence, Italy. I have","reasoning_details":[{"type":"reasoning.text","text":" information for Florence, Italy. I have","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" a","reasoning_details":[{"type":"reasoning.text","text":" a","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" weather","reasoning_details":[{"type":"reasoning.text","text":" weather","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" function","reasoning_details":[{"type":"reasoning.text","text":" function","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" available that takes","reasoning_details":[{"type":"reasoning.text","text":" available that takes","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" a location parameter.","reasoning_details":[{"type":"reasoning.text","text":" a location parameter.","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" The","reasoning_details":[{"type":"reasoning.text","text":" The","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" location","reasoning_details":[{"type":"reasoning.text","text":" location","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" is","reasoning_details":[{"type":"reasoning.text","text":" is","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" clearly","reasoning_details":[{"type":"reasoning.text","text":" clearly","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" specified as \"Florence, Italy\" so","reasoning_details":[{"type":"reasoning.text","text":" specified as \"Florence, Italy\" so","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" I have","reasoning_details":[{"type":"reasoning.text","text":" I have","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" all the required parameters to","reasoning_details":[{"type":"reasoning.text","text":" all the required parameters to","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" make the function call.","reasoning_details":[{"type":"reasoning.text","text":" make the function call.","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":"","reasoning_details":[{"type":"reasoning.text","text":"","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":"","reasoning_details":[{"type":"reasoning.text","text":"","signature":"EqUDCkYICxgCKkB94vhGG6xKjNnGimHMfRxMKRoDnfxu8X0ubqexC/CZ0gU1q1TlbdRN/J4R0tWVpSFl6fFlfjxBILkP/+4vk0rsEgwiokH4mommeOQbO0kaDDeTcsDepWKtbzn7RCIwM9YXOvgQOWNhGfjjNVXcLf20mCH4hUPTSpIp3F2WEOxI0CLOTKxuwGTgRB4axXhdKowCQwf95zMeALPR1ZZHRXqVm3Dm8Lf9W0kR2/G/irnQLoTR/lxZ5gB6FqUdPqNJHXmn3r6KxrQlxTM97UEZ0hEZHhBvwLk24e4KQitX5oHkNp+XMFCzjaym/Pryfjo4qxde8drr9TmHH1ajVYHkXue2L/RWEDrbUWITgtUP0CgkbAGijhpdJm4xVIMLHOD2cJS2+gChTu85uzdvdowlgHwMB7G5rHR+c1NB/2BV9iwhgVMgVjZlGB0SZmUoPEvPr2ZW2Y56tpnQ5d5zl4GdxImJBTSzoQzEKoGxt94MsXE207I0sp5L0Zzm+p4bDGTU6V0SI+eumemcejIt9O/jlGFFLf539LcU1+qeMWFdpBgB","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"toolu_01YVA3v6AcXDxaGjsKS8DiUq","type":"function","function":{"name":"weather","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"locati"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"on\": \"Flore"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"nce, Ital"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"y\"}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_iqjm7xgvli"}
+
+ data: {"id":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","object":"chat.completion.chunk","created":1770033404,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"provider_metadata":{"anthropic":{"usage":{"input_tokens":424,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":109,"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":162863.303643,"endTime":164602.735825,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":162863.303643,"endTime":164602.735825,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.002907","marketCost":"0.002907","generationId":"gen_01KGF3CMBNWVQFHD13H2B0XSBK","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":424,"completion_tokens":109,"total_tokens":533,"cost":0.002907,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002907},"system_fingerprint":"fp_iqjm7xgvli","generationId":"gen_01KGF3CMBNWVQFHD13H2B0XSBK"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.897754625s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1993
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"toolu_01YVA3v6AcXDxaGjsKS8DiUq","function":{"arguments":"{\"location\": \"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"anthropic-claude-v1","index":0,"signature":"EqUDCkYICxgCKkB94vhGG6xKjNnGimHMfRxMKRoDnfxu8X0ubqexC/CZ0gU1q1TlbdRN/J4R0tWVpSFl6fFlfjxBILkP/+4vk0rsEgwiokH4mommeOQbO0kaDDeTcsDepWKtbzn7RCIwM9YXOvgQOWNhGfjjNVXcLf20mCH4hUPTSpIp3F2WEOxI0CLOTKxuwGTgRB4axXhdKowCQwf95zMeALPR1ZZHRXqVm3Dm8Lf9W0kR2/G/irnQLoTR/lxZ5gB6FqUdPqNJHXmn3r6KxrQlxTM97UEZ0hEZHhBvwLk24e4KQitX5oHkNp+XMFCzjaym/Pryfjo4qxde8drr9TmHH1ajVYHkXue2L/RWEDrbUWITgtUP0CgkbAGijhpdJm4xVIMLHOD2cJS2+gChTu85uzdvdowlgHwMB7G5rHR+c1NB/2BV9iwhgVMgVjZlGB0SZmUoPEvPr2ZW2Y56tpnQ5d5zl4GdxImJBTSzoQzEKoGxt94MsXE207I0sp5L0Zzm+p4bDGTU6V0SI+eumemcejIt9O/jlGFFLf539LcU1+qeMWFdpBgB","text":"The user is asking for weather information for Florence, Italy. I have a weather function available that takes a location parameter. The location is clearly specified as \"Florence, Italy\" so I have all the required parameters to make the function call.","type":"reasoning.text"}],"reasoning":"The user is asking for weather information for Florence, Italy. I have a weather function available that takes a location parameter. The location is clearly specified as \"Florence, Italy\" so I have all the required parameters to make the function call."},{"content":"40 C","tool_call_id":"toolu_01YVA3v6AcXDxaGjsKS8DiUq","role":"tool"}],"model":"anthropic/claude-sonnet-4","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"enabled":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF3CQFX23W6JXADQ1QTEY98","object":"chat.completion.chunk","created":1770033406,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_95h77ud38a"}
+
+ data: {"id":"gen_01KGF3CQFX23W6JXADQ1QTEY98","object":"chat.completion.chunk","created":1770033406,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"The current"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_95h77ud38a"}
+
+ data: {"id":"gen_01KGF3CQFX23W6JXADQ1QTEY98","object":"chat.completion.chunk","created":1770033406,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" weather in Florence, Italy is 40"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_95h77ud38a"}
+
+ data: {"id":"gen_01KGF3CQFX23W6JXADQ1QTEY98","object":"chat.completion.chunk","created":1770033406,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"°C (104°F). That"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_95h77ud38a"}
+
+ data: {"id":"gen_01KGF3CQFX23W6JXADQ1QTEY98","object":"chat.completion.chunk","created":1770033406,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"'s quite"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_95h77ud38a"}
+
+ data: {"id":"gen_01KGF3CQFX23W6JXADQ1QTEY98","object":"chat.completion.chunk","created":1770033406,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" hot!"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_95h77ud38a"}
+
+ data: {"id":"gen_01KGF3CQFX23W6JXADQ1QTEY98","object":"chat.completion.chunk","created":1770033406,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" It"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_95h77ud38a"}
+
+ data: {"id":"gen_01KGF3CQFX23W6JXADQ1QTEY98","object":"chat.completion.chunk","created":1770033406,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"'s a very"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_95h77ud38a"}
+
+ data: {"id":"gen_01KGF3CQFX23W6JXADQ1QTEY98","object":"chat.completion.chunk","created":1770033406,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" warm day in"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_95h77ud38a"}
+
+ data: {"id":"gen_01KGF3CQFX23W6JXADQ1QTEY98","object":"chat.completion.chunk","created":1770033406,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" Florence."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_95h77ud38a"}
+
+ data: {"id":"gen_01KGF3CQFX23W6JXADQ1QTEY98","object":"chat.completion.chunk","created":1770033406,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"provider_metadata":{"anthropic":{"usage":{"input_tokens":548,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":34,"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":4956.113352,"endTime":6171.847632,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":4956.113352,"endTime":6171.847632,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.002154","marketCost":"0.002154","generationId":"gen_01KGF3CQFX23W6JXADQ1QTEY98","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":548,"completion_tokens":34,"total_tokens":582,"cost":0.002154,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002154},"system_fingerprint":"fp_95h77ud38a","generationId":"gen_01KGF3CQFX23W6JXADQ1QTEY98"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.345717s
diff --git a/internal/fantasy/providertests/testdata/TestVercelThinking/claude-sonnet-4-sig/thinking.yaml b/internal/fantasy/providertests/testdata/TestVercelThinking/claude-sonnet-4-sig/thinking.yaml
new file mode 100644
index 000000000..574caa7ed
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelThinking/claude-sonnet-4-sig/thinking.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 479
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"anthropic/claude-sonnet-4","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"enabled":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF3CESJKXWS3VT4KZ7Z4H0S","object":"chat.completion","created":1770033398,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"message":{"role":"assistant","content":null,"reasoning":"The user is asking for weather information for Florence, Italy. I have a weather function available that takes a location parameter. The location is clearly specified as \"Florence, Italy\" so I have all the required parameters to make the function call.","reasoning_details":[{"type":"reasoning.text","text":"The user is asking for weather information for Florence, Italy. I have a weather function available that takes a location parameter. The location is clearly specified as \"Florence, Italy\" so I have all the required parameters to make the function call.","signature":"EqUDCkYICxgCKkB94vhGG6xKjNnGimHMfRxMKRoDnfxu8X0ubqexC/CZ0gU1q1TlbdRN/J4R0tWVpSFl6fFlfjxBILkP/+4vk0rsEgxEmjcKGGfHXogpkvoaDIJiOn8VbzE+KqPLBCIwyk+17OatdTJTKgOrfaX2tZL5Qmx9Mm1mCs2Djj2mmm5pnDwGymarqbOQn4al+112KowCfd3UWJ1pnfvuMtHp4LCLBjiLWnPPq+gZnlgsNecPBSBXKDt73jMGOd0NQBN7lOOZBy2AR9oQzKpCbyH5CY475OUYjbr8Rz+Xi3JIBit+AL96bsHSares7CpY1y2KVT0d8EPZZMmRr2SEK0AYtccALMpN3n/+QTu0eOlC1Jsv1ygyiRhoPszCqW98h/OdlMzWQyLu60Hir9D91svBFCQ1umLHR3wiJQ/fN025OVtiffGmkjcYWuvEChRS+fN21kSeDOcjbU2nqhRBWJc61RFRjJ8scShRpYoTQn5tNOeSsRIgAfzfmYRK1tp3NzhGDbQM/t6ytgrsToE9ehXnyKIKCVknQl5mkfT3Jw5S+xgB","format":"anthropic-claude-v1","index":0}],"tool_calls":[{"id":"toolu_01QueSgW64L24gT3TZdWbizV","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence, Italy\"}"}}],"provider_metadata":{"anthropic":{"usage":{"input_tokens":424,"output_tokens":109,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":7765415.569026,"endTime":7767783.415776,"statusCode":200,"providerResponseId":"msg_015136shD3sTPiMES5sYeqsD"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.002907","marketCost":"0.002907","generationId":"gen_01KGF3CESJKXWS3VT4KZ7Z4H0S","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":424,"completion_tokens":109,"total_tokens":533,"cost":0.002907,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002907},"system_fingerprint":"fp_zqq5kppgz1","generationId":"gen_01KGF3CESJKXWS3VT4KZ7Z4H0S"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.513099333s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1938
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"toolu_01QueSgW64L24gT3TZdWbizV","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"anthropic-claude-v1","index":0,"signature":"EqUDCkYICxgCKkB94vhGG6xKjNnGimHMfRxMKRoDnfxu8X0ubqexC/CZ0gU1q1TlbdRN/J4R0tWVpSFl6fFlfjxBILkP/+4vk0rsEgxEmjcKGGfHXogpkvoaDIJiOn8VbzE+KqPLBCIwyk+17OatdTJTKgOrfaX2tZL5Qmx9Mm1mCs2Djj2mmm5pnDwGymarqbOQn4al+112KowCfd3UWJ1pnfvuMtHp4LCLBjiLWnPPq+gZnlgsNecPBSBXKDt73jMGOd0NQBN7lOOZBy2AR9oQzKpCbyH5CY475OUYjbr8Rz+Xi3JIBit+AL96bsHSares7CpY1y2KVT0d8EPZZMmRr2SEK0AYtccALMpN3n/+QTu0eOlC1Jsv1ygyiRhoPszCqW98h/OdlMzWQyLu60Hir9D91svBFCQ1umLHR3wiJQ/fN025OVtiffGmkjcYWuvEChRS+fN21kSeDOcjbU2nqhRBWJc61RFRjJ8scShRpYoTQn5tNOeSsRIgAfzfmYRK1tp3NzhGDbQM/t6ytgrsToE9ehXnyKIKCVknQl5mkfT3Jw5S+xgB","text":"The user is asking for weather information for Florence, Italy. I have a weather function available that takes a location parameter. The location is clearly specified as \"Florence, Italy\" so I have all the required parameters to make the function call.","type":"reasoning.text"}],"reasoning":"The user is asking for weather information for Florence, Italy. I have a weather function available that takes a location parameter. The location is clearly specified as \"Florence, Italy\" so I have all the required parameters to make the function call."},{"content":"40 C","tool_call_id":"toolu_01QueSgW64L24gT3TZdWbizV","role":"tool"}],"model":"anthropic/claude-sonnet-4","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"enabled":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF3CH7MBCX5TG98WJF2BTYT","object":"chat.completion","created":1770033402,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"message":{"role":"assistant","content":"The current weather in Florence, Italy is 40°C (104°F). That''s quite hot! It''s a very warm day in Florence.","provider_metadata":{"anthropic":{"usage":{"input_tokens":548,"output_tokens":34,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":1505902.416236,"endTime":1508977.489215,"statusCode":200,"providerResponseId":"msg_01RG65Q4UDkyK2BAznqpD7GE"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.002154","marketCost":"0.002154","generationId":"gen_01KGF3CH7MBCX5TG98WJF2BTYT","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":548,"completion_tokens":34,"total_tokens":582,"cost":0.002154,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002154},"system_fingerprint":"fp_9mdcax34m","generationId":"gen_01KGF3CH7MBCX5TG98WJF2BTYT"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 3.165230708s
diff --git a/internal/fantasy/providertests/testdata/TestVercelThinking/claude-sonnet-4/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelThinking/claude-sonnet-4/thinking-streaming.yaml
new file mode 100644
index 000000000..d60e25640
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelThinking/claude-sonnet-4/thinking-streaming.yaml
@@ -0,0 +1,171 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 533
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"anthropic/claude-sonnet-4","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"enabled":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":"The user is asking for","reasoning_details":[{"type":"reasoning.text","text":"The user is asking for","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" weather","reasoning_details":[{"type":"reasoning.text","text":" weather","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" information for Florence, Italy. I have","reasoning_details":[{"type":"reasoning.text","text":" information for Florence, Italy. I have","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" a weather","reasoning_details":[{"type":"reasoning.text","text":" a weather","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" function available","reasoning_details":[{"type":"reasoning.text","text":" function available","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" that takes","reasoning_details":[{"type":"reasoning.text","text":" that takes","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" a location parameter.","reasoning_details":[{"type":"reasoning.text","text":" a location parameter.","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" The","reasoning_details":[{"type":"reasoning.text","text":" The","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" user has","reasoning_details":[{"type":"reasoning.text","text":" user has","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" provided the location as","reasoning_details":[{"type":"reasoning.text","text":" provided the location as","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" \"Florence, Italy\" which","reasoning_details":[{"type":"reasoning.text","text":" \"Florence, Italy\" which","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" is specific","reasoning_details":[{"type":"reasoning.text","text":" is specific","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" enough for","reasoning_details":[{"type":"reasoning.text","text":" enough for","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" the weather function.","reasoning_details":[{"type":"reasoning.text","text":" the weather function.","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" I have","reasoning_details":[{"type":"reasoning.text","text":" I have","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" all the required parameters to make the function","reasoning_details":[{"type":"reasoning.text","text":" all the required parameters to make the function","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":" call.","reasoning_details":[{"type":"reasoning.text","text":" call.","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":"","reasoning_details":[{"type":"reasoning.text","text":"","signature":"","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"reasoning":"","reasoning_details":[{"type":"reasoning.text","text":"","signature":"EtYDCkYICxgCKkD9mnV1Hds6SXvRNDaaVGP9IRFYqdtRgWJOe8g0L7Ud8hYHbJ+xtiLx6BOulBrCSpqk0qL0Ppqn5ZjggFDrpOl9Egxi/ODyXHn/gED5bk8aDDdrhkgNzG+ZAsd/4CIwZMUjUcbSZEuLEEhx8gHG8s25q5UMj5UqA0XYiTXvWMiyDOplOPRYIpyFzeBIzoHTKr0C51eUyyUS9b37iYdk2gZ5G+fU3BJMMgrDaNCSeiT6A47YXYO+w4sN60Fr3fXXyfNewEnfycIkFcsSUeoraqRtMXYmtpZ1U3hTMNf97Ve2ITFHwdKtZqo6KOV3PZEPPXBA8y59K6s+WD8kEKWb3126miv3moQ8fH2A5Dtk9bzXqNtWnAFI97JnnZgvmSH6tqYS2RkHMtj31LPaxYjWjqc2IusllrCoI1WEsu5bpABezlPKEWayq7FHjqUyeF+w4hEkQ4mjRjLHsVfNC2Pb79DEuGttQ8esezKiaVLhWZ8NngPU/Kv0J8Mtc0DTbBxlk58PMwO2zVeLAuthixkX5OiSfVtNVX3DDe4odTAxiFouPl5OOw964A+L6u27r+7nsurLHkZkrw7hpSP7saLGSUUX3++WmIFEZnz/d/cqCU4YAQ==","format":"anthropic-claude-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"toolu_01LCB6569oxJKyPag7eFnnjx","type":"function","function":{"name":"weather","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"loca"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"tio"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"Flore"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"nc"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"e,"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" Italy\"}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_moyu1cwxfr"}
+
+ data: {"id":"gen_01KGF3AVVKYFARGPVSM4MZY14H","object":"chat.completion.chunk","created":1770033348,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"provider_metadata":{"anthropic":{"usage":{"input_tokens":424,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":118,"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":7093511.188939,"endTime":7097175.93529,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":7093511.188939,"endTime":7097175.93529,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.003042","marketCost":"0.003042","generationId":"gen_01KGF3AVVKYFARGPVSM4MZY14H","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":424,"completion_tokens":118,"total_tokens":542,"cost":0.003042,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.003042},"system_fingerprint":"fp_moyu1cwxfr","generationId":"gen_01KGF3AVVKYFARGPVSM4MZY14H"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 3.850747333s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2159
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"toolu_01LCB6569oxJKyPag7eFnnjx","function":{"arguments":"{\"location\": \"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"anthropic-claude-v1","index":0,"signature":"EtYDCkYICxgCKkD9mnV1Hds6SXvRNDaaVGP9IRFYqdtRgWJOe8g0L7Ud8hYHbJ+xtiLx6BOulBrCSpqk0qL0Ppqn5ZjggFDrpOl9Egxi/ODyXHn/gED5bk8aDDdrhkgNzG+ZAsd/4CIwZMUjUcbSZEuLEEhx8gHG8s25q5UMj5UqA0XYiTXvWMiyDOplOPRYIpyFzeBIzoHTKr0C51eUyyUS9b37iYdk2gZ5G+fU3BJMMgrDaNCSeiT6A47YXYO+w4sN60Fr3fXXyfNewEnfycIkFcsSUeoraqRtMXYmtpZ1U3hTMNf97Ve2ITFHwdKtZqo6KOV3PZEPPXBA8y59K6s+WD8kEKWb3126miv3moQ8fH2A5Dtk9bzXqNtWnAFI97JnnZgvmSH6tqYS2RkHMtj31LPaxYjWjqc2IusllrCoI1WEsu5bpABezlPKEWayq7FHjqUyeF+w4hEkQ4mjRjLHsVfNC2Pb79DEuGttQ8esezKiaVLhWZ8NngPU/Kv0J8Mtc0DTbBxlk58PMwO2zVeLAuthixkX5OiSfVtNVX3DDe4odTAxiFouPl5OOw964A+L6u27r+7nsurLHkZkrw7hpSP7saLGSUUX3++WmIFEZnz/d/cqCU4YAQ==","text":"The user is asking for weather information for Florence, Italy. I have a weather function available that takes a location parameter. The user has provided the location as \"Florence, Italy\" which is specific enough for the weather function. I have all the required parameters to make the function call.","type":"reasoning.text"}],"reasoning":"The user is asking for weather information for Florence, Italy. I have a weather function available that takes a location parameter. The user has provided the location as \"Florence, Italy\" which is specific enough for the weather function. I have all the required parameters to make the function call."},{"content":"40 C","tool_call_id":"toolu_01LCB6569oxJKyPag7eFnnjx","role":"tool"}],"model":"anthropic/claude-sonnet-4","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"enabled":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"The current"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" weather in Florence, Italy is 40"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"°C (104°F). That"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"'s quite"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" hot"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"! This is a"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" high"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" temperature that"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" suggests"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" very"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" warm,"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" potentially"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" uncomfortable"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" weather conditions"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":". You might want to stay"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" hydrated and seek"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" air"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" conditioning"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" or shade if"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" you're planning to be in"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" Florence"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":" today"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_wkyq4vz6ii"}
+
+ data: {"id":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","object":"chat.completion.chunk","created":1770033350,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"delta":{"provider_metadata":{"anthropic":{"usage":{"input_tokens":557,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":63,"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":1456427.826085,"endTime":1457451.848654,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":1456427.826085,"endTime":1457451.848654,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.002616","marketCost":"0.002616","generationId":"gen_01KGF3B0WTSB5GEBEY54E4B78Q","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":557,"completion_tokens":63,"total_tokens":620,"cost":0.002616,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002616},"system_fingerprint":"fp_wkyq4vz6ii","generationId":"gen_01KGF3B0WTSB5GEBEY54E4B78Q"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 1.12508025s
diff --git a/internal/fantasy/providertests/testdata/TestVercelThinking/claude-sonnet-4/thinking.yaml b/internal/fantasy/providertests/testdata/TestVercelThinking/claude-sonnet-4/thinking.yaml
new file mode 100644
index 000000000..571981830
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelThinking/claude-sonnet-4/thinking.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 479
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"anthropic/claude-sonnet-4","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"enabled":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF3AQBSB35WNS62SPSARQ6W","object":"chat.completion","created":1770033342,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"message":{"role":"assistant","content":null,"reasoning":"The user is asking for weather information for Florence, Italy. I have access to a weather function that requires a \"location\" parameter. The user has provided the location as \"Florence, Italy\" which is specific enough to use for the weather query.\n\nI should call the weather function with \"Florence, Italy\" as the location parameter.","reasoning_details":[{"type":"reasoning.text","text":"The user is asking for weather information for Florence, Italy. I have access to a weather function that requires a \"location\" parameter. The user has provided the location as \"Florence, Italy\" which is specific enough to use for the weather query.\n\nI should call the weather function with \"Florence, Italy\" as the location parameter.","signature":"EvcDCkYICxgCKkAcv+JiUJrSmNoeyAKGVOi/csdYyFzgyZwNioa99UTlL/tPju5ML6OZ4LOvKaFwaUZyzcNW4uQLu7jI2eVLu1iBEgz1tmAQP8hgL/Hy0u0aDBov3mK2gXR/f7z0iiIw8orugLuO+L2R5wuK35rGJkQhVHAphISN2F2FNjrGts/gbB+dJtP1ncNCWYFSp2NjKt4Cq7EYeQ0x9ie1oKSCG9n9bGZ0br1TVg4ClNZEQQou4gAMGZonFMnDy0uwPwk5F1rujCQbIJVzttyhb/lVmqUeEy/IFbYDmIi/1MAHlpN8qhX/0NhviIlZGobT7wzZUuNgQYT10+Wr8AfCNuHrMfjN1XnW+72e2p7QmcMEBcR8/sO24stZFAuTrnZytWOrINqsgbuEKcklViQw8RqQNkWUOGlOS+BOWZXIcLinY5LCPftHjLCKrFFG37bGwWKlWpbu9z/whcQ9UVE+TnrIdnhwdhxoljIbuzDBQTuY8MhlOXBzUujm6QaqxOWX0bnyPe+8eq+T1zsq3BLU2OLg5P/6rMZCYxrSjCTSnX0dM/UKxasn7cqT0QwWeVt1hMRDdO3heoFOfQgHmx9w4RuDvlZ9xh0xMKG/Amy8PhqU8tzE8U1+uMCl1PpaOa42MpcWleUklf24hkwZVqM488rdUjIYAQ==","format":"anthropic-claude-v1","index":0}],"tool_calls":[{"id":"toolu_01VvThmBhnhGHEcRJeyCRSHe","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence, Italy\"}"}}],"provider_metadata":{"anthropic":{"usage":{"input_tokens":424,"output_tokens":129,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":7088911.419434,"endTime":7091508.412367,"statusCode":200,"providerResponseId":"msg_01Um7d6HWfESfBhnukpiBeuy"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.003207","marketCost":"0.003207","generationId":"gen_01KGF3AQBSB35WNS62SPSARQ6W","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":424,"completion_tokens":129,"total_tokens":553,"cost":0.003207,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.003207},"system_fingerprint":"fp_da7b9rssdj","generationId":"gen_01KGF3AQBSB35WNS62SPSARQ6W"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.754280458s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2226
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"toolu_01VvThmBhnhGHEcRJeyCRSHe","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning":"The user is asking for weather information for Florence, Italy. I have access to a weather function that requires a \"location\" parameter. The user has provided the location as \"Florence, Italy\" which is specific enough to use for the weather query.\n\nI should call the weather function with \"Florence, Italy\" as the location parameter.","reasoning_details":[{"format":"anthropic-claude-v1","index":0,"signature":"EvcDCkYICxgCKkAcv+JiUJrSmNoeyAKGVOi/csdYyFzgyZwNioa99UTlL/tPju5ML6OZ4LOvKaFwaUZyzcNW4uQLu7jI2eVLu1iBEgz1tmAQP8hgL/Hy0u0aDBov3mK2gXR/f7z0iiIw8orugLuO+L2R5wuK35rGJkQhVHAphISN2F2FNjrGts/gbB+dJtP1ncNCWYFSp2NjKt4Cq7EYeQ0x9ie1oKSCG9n9bGZ0br1TVg4ClNZEQQou4gAMGZonFMnDy0uwPwk5F1rujCQbIJVzttyhb/lVmqUeEy/IFbYDmIi/1MAHlpN8qhX/0NhviIlZGobT7wzZUuNgQYT10+Wr8AfCNuHrMfjN1XnW+72e2p7QmcMEBcR8/sO24stZFAuTrnZytWOrINqsgbuEKcklViQw8RqQNkWUOGlOS+BOWZXIcLinY5LCPftHjLCKrFFG37bGwWKlWpbu9z/whcQ9UVE+TnrIdnhwdhxoljIbuzDBQTuY8MhlOXBzUujm6QaqxOWX0bnyPe+8eq+T1zsq3BLU2OLg5P/6rMZCYxrSjCTSnX0dM/UKxasn7cqT0QwWeVt1hMRDdO3heoFOfQgHmx9w4RuDvlZ9xh0xMKG/Amy8PhqU8tzE8U1+uMCl1PpaOa42MpcWleUklf24hkwZVqM488rdUjIYAQ==","text":"The user is asking for weather information for Florence, Italy. I have access to a weather function that requires a \"location\" parameter. The user has provided the location as \"Florence, Italy\" which is specific enough to use for the weather query.\n\nI should call the weather function with \"Florence, Italy\" as the location parameter.","type":"reasoning.text"}]},{"content":"40 C","tool_call_id":"toolu_01VvThmBhnhGHEcRJeyCRSHe","role":"tool"}],"model":"anthropic/claude-sonnet-4","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"enabled":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF3AT2W4QFA7ZW3ASZ8571P","object":"chat.completion","created":1770033344,"model":"anthropic/claude-sonnet-4","choices":[{"index":0,"message":{"role":"assistant","content":"The current weather in Florence, Italy is 40°C (104°F). That''s quite hot! It''s a very warm day in Florence.","provider_metadata":{"anthropic":{"usage":{"input_tokens":568,"output_tokens":34,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"service_tier":"standard"},"cacheCreationInputTokens":0,"stopSequence":null,"container":null},"gateway":{"routing":{"originalModelId":"anthropic/claude-sonnet-4","resolvedProvider":"anthropic","resolvedProviderApiModelId":"claude-sonnet-4-20250514","internalResolvedModelId":"anthropic:claude-sonnet-4-20250514","fallbacksAvailable":["vertexAnthropic","bedrock"],"internalReasoning":"Selected anthropic as preferred provider for claude-sonnet-4. 2 fallback(s) available: vertexAnthropic, bedrock","planningReasoning":"System credentials planned for: anthropic, vertexAnthropic, bedrock. Total execution order: anthropic(system) ā vertexAnthropic(system) ā bedrock(system)","canonicalSlug":"anthropic/claude-sonnet-4","finalProvider":"anthropic","attempts":[{"provider":"anthropic","internalModelId":"anthropic:claude-sonnet-4-20250514","providerApiModelId":"claude-sonnet-4-20250514","credentialType":"system","success":true,"startTime":7712011.428399,"endTime":7713764.18868,"statusCode":200,"providerResponseId":"msg_01Xc77vidcSXUVZGp5byrDUm"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"anthropic/claude-sonnet-4","canonicalSlug":"anthropic/claude-sonnet-4","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.002214","marketCost":"0.002214","generationId":"gen_01KGF3AT2W4QFA7ZW3ASZ8571P","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":568,"completion_tokens":34,"total_tokens":602,"cost":0.002214,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.002214},"system_fingerprint":"fp_k3wp9lnz45","generationId":"gen_01KGF3AT2W4QFA7ZW3ASZ8571P"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 1.837599167s
diff --git a/internal/fantasy/providertests/testdata/TestVercelThinking/gemini-3-pro-preview/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelThinking/gemini-3-pro-preview/thinking-streaming.yaml
new file mode 100644
index 000000000..c43673bda
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelThinking/gemini-3-pro-preview/thinking-streaming.yaml
@@ -0,0 +1,87 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 535
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"google/gemini-3-pro-preview","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"enabled":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF3C0Q49GHB7YJE7PKYYXEK","object":"chat.completion.chunk","created":1770033385,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_q2vuvpzyv8"}
+
+ data: {"id":"gen_01KGF3C0Q49GHB7YJE7PKYYXEK","object":"chat.completion.chunk","created":1770033385,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"reasoning":"**Analyzing the User's Query**\n\nI'm focused on understanding the user's intent. My primary task is to identify the location for the weather query. It's evident the user wants weather data for Florence, Italy. I'll utilize the `weather` tool and set the `location` parameter accordingly.\n\n\n","reasoning_details":[{"type":"reasoning.text","text":"**Analyzing the User's Query**\n\nI'm focused on understanding the user's intent. My primary task is to identify the location for the weather query. It's evident the user wants weather data for Florence, Italy. I'll utilize the `weather` tool and set the `location` parameter accordingly.\n\n\n","format":"google-gemini-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_q2vuvpzyv8"}
+
+ data: {"id":"gen_01KGF3C0Q49GHB7YJE7PKYYXEK","object":"chat.completion.chunk","created":1770033385,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"SmUJTLmrRxi0lu0v","type":"function","function":{"name":"weather","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_q2vuvpzyv8"}
+
+ data: {"id":"gen_01KGF3C0Q49GHB7YJE7PKYYXEK","object":"chat.completion.chunk","created":1770033385,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"location\":\"Florence, Italy\"}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_q2vuvpzyv8"}
+
+ data: {"id":"gen_01KGF3C0Q49GHB7YJE7PKYYXEK","object":"chat.completion.chunk","created":1770033385,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"reasoning_details":[{"type":"reasoning.encrypted","data":"CiQBjz1rXzHrIG8VyKxoyvNfn34I0fU0MFB3Xbo4yGmi5lXxz9oKZgGPPWtfH7TJlamiXjXsugVyW8VxgOUJprUjmiUwJi/stNqMS3LooRoUA1fBkdgztTDDIGWmRMXQtWqouGUTAeueCke7VJzsJm3GwC5Czg9laR24rLZ/AU+1oJpvT5AmZHm0AYnOGAp3AY89a1+1SkejrgsX83pkwVBjFrYRepT+UEelh8Kexyj/KndelV/yYbA+gWgGGSMKe4zq3JKh99Toc1/OqRXykl9qKTNXZj1xaIkP98KH/4mRnVw4Mvc3mE2R97bmzKTFSxzAlJ7+XFtYnZjg7PiNxuwEiZIlG3kKNAGPPWtfzlrIZvrYjj2PtuKOaHbd5iP/2u4dRMmmPZ8fi8DHZdSpnDnJAKI/TVQikZmdBZo=","format":"google-gemini-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_q2vuvpzyv8"}
+
+ data: {"id":"gen_01KGF3C0Q49GHB7YJE7PKYYXEK","object":"chat.completion.chunk","created":1770033385,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":39,"promptTokenCount":28,"candidatesTokenCount":9,"totalTokenCount":76,"trafficType":"ON_DEMAND"}},"gateway":{"routing":{"originalModelId":"google/gemini-3-pro-preview","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-3-pro-preview","internalResolvedModelId":"vertex:gemini-3-pro-preview","fallbacksAvailable":["google"],"internalReasoning":"Selected vertex as preferred provider for gemini-3-pro-preview. 1 fallback(s) available: google","planningReasoning":"System credentials planned for: vertex, google. Total execution order: vertex(system) ā google(system)","canonicalSlug":"google/gemini-3-pro-preview","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":7750944.987373,"endTime":7754447.770022,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-3-pro-preview","canonicalSlug":"google/gemini-3-pro-preview","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":7750944.987373,"endTime":7754447.770022,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.000632","marketCost":"0.000632","generationId":"gen_01KGF3C0Q49GHB7YJE7PKYYXEK","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":28,"completion_tokens":9,"total_tokens":37,"cost":0.000632,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":39,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.000632},"system_fingerprint":"fp_q2vuvpzyv8","generationId":"gen_01KGF3C0Q49GHB7YJE7PKYYXEK"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 3.681428625s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1286
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"SmUJTLmrRxi0lu0v","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"data":"CiQBjz1rXzHrIG8VyKxoyvNfn34I0fU0MFB3Xbo4yGmi5lXxz9oKZgGPPWtfH7TJlamiXjXsugVyW8VxgOUJprUjmiUwJi/stNqMS3LooRoUA1fBkdgztTDDIGWmRMXQtWqouGUTAeueCke7VJzsJm3GwC5Czg9laR24rLZ/AU+1oJpvT5AmZHm0AYnOGAp3AY89a1+1SkejrgsX83pkwVBjFrYRepT+UEelh8Kexyj/KndelV/yYbA+gWgGGSMKe4zq3JKh99Toc1/OqRXykl9qKTNXZj1xaIkP98KH/4mRnVw4Mvc3mE2R97bmzKTFSxzAlJ7+XFtYnZjg7PiNxuwEiZIlG3kKNAGPPWtfzlrIZvrYjj2PtuKOaHbd5iP/2u4dRMmmPZ8fi8DHZdSpnDnJAKI/TVQikZmdBZo=","format":"google-gemini-v1","index":0,"type":"reasoning.encrypted"}]},{"content":"40 C","tool_call_id":"SmUJTLmrRxi0lu0v","role":"tool"}],"model":"google/gemini-3-pro-preview","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"enabled":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF3C4C0A7ZEXSENPBN82KKW","object":"chat.completion.chunk","created":1770033396,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kt7kxbesam"}
+
+ data: {"id":"gen_01KGF3C4C0A7ZEXSENPBN82KKW","object":"chat.completion.chunk","created":1770033396,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"reasoning":"**Analyzing Weather Data**\n\nI've just received the weather data for Florence. My current task is to clearly convey the 40 degrees Celsius temperature reading to the user. I'm focusing on the best way to present this information so it's easily understood and actionable.\n\n\n","reasoning_details":[{"type":"reasoning.text","text":"**Analyzing Weather Data**\n\nI've just received the weather data for Florence. My current task is to clearly convey the 40 degrees Celsius temperature reading to the user. I'm focusing on the best way to present this information so it's easily understood and actionable.\n\n\n","format":"google-gemini-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kt7kxbesam"}
+
+ data: {"id":"gen_01KGF3C4C0A7ZEXSENPBN82KKW","object":"chat.completion.chunk","created":1770033396,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"content":"The current weather in Florence"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kt7kxbesam"}
+
+ data: {"id":"gen_01KGF3C4C0A7ZEXSENPBN82KKW","object":"chat.completion.chunk","created":1770033396,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"content":", Italy is 40°C."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_kt7kxbesam"}
+
+ data: {"id":"gen_01KGF3C4C0A7ZEXSENPBN82KKW","object":"chat.completion.chunk","created":1770033396,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"delta":{"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":29,"promptTokenCount":40,"candidatesTokenCount":14,"totalTokenCount":83,"trafficType":"ON_DEMAND"}},"gateway":{"routing":{"originalModelId":"google/gemini-3-pro-preview","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-3-pro-preview","internalResolvedModelId":"vertex:gemini-3-pro-preview","fallbacksAvailable":["google"],"internalReasoning":"Selected vertex as preferred provider for gemini-3-pro-preview. 1 fallback(s) available: google","planningReasoning":"System credentials planned for: vertex, google. Total execution order: vertex(system) ā google(system)","canonicalSlug":"google/gemini-3-pro-preview","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":1491866.50627,"endTime":1502204.735086,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-3-pro-preview","canonicalSlug":"google/gemini-3-pro-preview","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":1491866.50627,"endTime":1502204.735086,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.000596","marketCost":"0.000596","generationId":"gen_01KGF3C4C0A7ZEXSENPBN82KKW","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":40,"completion_tokens":14,"total_tokens":54,"cost":0.000596,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":29,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.000596},"system_fingerprint":"fp_kt7kxbesam","generationId":"gen_01KGF3C4C0A7ZEXSENPBN82KKW"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 10.48104525s
diff --git a/internal/fantasy/providertests/testdata/TestVercelThinking/gemini-3-pro-preview/thinking.yaml b/internal/fantasy/providertests/testdata/TestVercelThinking/gemini-3-pro-preview/thinking.yaml
new file mode 100644
index 000000000..5dc01fb6a
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelThinking/gemini-3-pro-preview/thinking.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 481
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"google/gemini-3-pro-preview","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"enabled":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF3BTEQ7ZXNXTXM5HCM0ZW5","object":"chat.completion","created":1770033379,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"message":{"role":"assistant","content":null,"reasoning":"**Determining the Weather**\n\nI''ve identified the need for weather data. I believe the `weather` function is a solid choice. It''s now a matter of calling this function. I''ll pass it ''Florence, Italy'' to retrieve the current conditions.\n\n\n","reasoning_details":[{"type":"reasoning.text","text":"**Determining the Weather**\n\nI''ve identified the need for weather data. I believe the `weather` function is a solid choice. It''s now a matter of calling this function. I''ll pass it ''Florence, Italy'' to retrieve the current conditions.\n\n\n","format":"google-gemini-v1","index":0}],"tool_calls":[{"id":"Zwo8e1JcXjoJ0bPs","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence, Italy\"}"}}],"provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"thoughtsTokenCount":67,"promptTokenCount":28,"candidatesTokenCount":9,"totalTokenCount":104,"trafficType":"PROVISIONED_THROUGHPUT"}},"gateway":{"routing":{"originalModelId":"google/gemini-3-pro-preview","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-3-pro-preview","internalResolvedModelId":"vertex:gemini-3-pro-preview","fallbacksAvailable":["google"],"internalReasoning":"Selected vertex as preferred provider for gemini-3-pro-preview. 1 fallback(s) available: google","planningReasoning":"System credentials planned for: vertex, google. Total execution order: vertex(system) ā google(system)","canonicalSlug":"google/gemini-3-pro-preview","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":390947.964322,"endTime":394738.481613,"statusCode":200,"providerResponseId":"35CAacnTN9X8tfAPg7j5QA"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-3-pro-preview","canonicalSlug":"google/gemini-3-pro-preview","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.000968","marketCost":"0.000968","generationId":"gen_01KGF3BTEQ7ZXNXTXM5HCM0ZW5","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":28,"completion_tokens":9,"total_tokens":37,"cost":0.000968,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":67,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.000968},"system_fingerprint":"fp_t3b6jfaxsx","generationId":"gen_01KGF3BTEQ7ZXNXTXM5HCM0ZW5"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 4.135991625s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 1114
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"Zwo8e1JcXjoJ0bPs","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"google-gemini-v1","index":0,"text":"**Determining the Weather**\n\nI''ve identified the need for weather data. I believe the `weather` function is a solid choice. It''s now a matter of calling this function. I''ll pass it ''Florence, Italy'' to retrieve the current conditions.\n\n\n","type":"reasoning.text"},{"format":"google-gemini-v1","index":0,"type":"reasoning.encrypted"}]},{"content":"40 C","tool_call_id":"Zwo8e1JcXjoJ0bPs","role":"tool"}],"model":"google/gemini-3-pro-preview","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"enabled":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF3BYDZXE5BFFQQRPX4SSCP","object":"chat.completion","created":1770033382,"model":"google/gemini-3-pro-preview","choices":[{"index":0,"message":{"role":"assistant","content":"The current temperature in Florence, Italy is 40°C.","provider_metadata":{"google":{"promptFeedback":null,"groundingMetadata":null,"urlContextMetadata":null,"safetyRatings":null,"usageMetadata":{"promptTokenCount":97,"candidatesTokenCount":14,"totalTokenCount":111,"trafficType":"PROVISIONED_THROUGHPUT"}},"gateway":{"routing":{"originalModelId":"google/gemini-3-pro-preview","resolvedProvider":"vertex","resolvedProviderApiModelId":"gemini-3-pro-preview","internalResolvedModelId":"vertex:gemini-3-pro-preview","fallbacksAvailable":["google"],"internalReasoning":"Selected vertex as preferred provider for gemini-3-pro-preview. 1 fallback(s) available: google","planningReasoning":"System credentials planned for: vertex, google. Total execution order: vertex(system) ā google(system)","canonicalSlug":"google/gemini-3-pro-preview","finalProvider":"vertex","attempts":[{"provider":"vertex","internalModelId":"vertex:gemini-3-pro-preview","providerApiModelId":"gemini-3-pro-preview","credentialType":"system","success":true,"startTime":7748615.626226,"endTime":7750847.973285,"statusCode":200,"providerResponseId":"45CAae7FNaahmPUPueDE6QU"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"google/gemini-3-pro-preview","canonicalSlug":"google/gemini-3-pro-preview","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.000362","marketCost":"0.000362","generationId":"gen_01KGF3BYDZXE5BFFQQRPX4SSCP","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":97,"completion_tokens":14,"total_tokens":111,"cost":0.000362,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.000362},"system_fingerprint":"fp_02078i909k","generationId":"gen_01KGF3BYDZXE5BFFQQRPX4SSCP"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 2.353875042s
diff --git a/internal/fantasy/providertests/testdata/TestVercelThinking/gpt-5/thinking-streaming.yaml b/internal/fantasy/providertests/testdata/TestVercelThinking/gpt-5/thinking-streaming.yaml
new file mode 100644
index 000000000..289beba53
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelThinking/gpt-5/thinking-streaming.yaml
@@ -0,0 +1,343 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 520
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"openai/gpt-5","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"enabled":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":"**Getting","reasoning_details":[{"type":"reasoning.summary","summary":"**Getting","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" weather","reasoning_details":[{"type":"reasoning.summary","summary":" weather","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" information","reasoning_details":[{"type":"reasoning.summary","summary":" information","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":"**\n\nI","reasoning_details":[{"type":"reasoning.summary","summary":"**\n\nI","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" need","reasoning_details":[{"type":"reasoning.summary","summary":" need","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" to","reasoning_details":[{"type":"reasoning.summary","summary":" to","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" retrieve","reasoning_details":[{"type":"reasoning.summary","summary":" retrieve","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" weather","reasoning_details":[{"type":"reasoning.summary","summary":" weather","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" using","reasoning_details":[{"type":"reasoning.summary","summary":" using","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" designated","reasoning_details":[{"type":"reasoning.summary","summary":" designated","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" tool","reasoning_details":[{"type":"reasoning.summary","summary":" tool","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" specifically","reasoning_details":[{"type":"reasoning.summary","summary":" specifically","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" functions","reasoning_details":[{"type":"reasoning.summary","summary":" functions","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":".weather","reasoning_details":[{"type":"reasoning.summary","summary":".weather","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" with","reasoning_details":[{"type":"reasoning.summary","summary":" with","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" location","reasoning_details":[{"type":"reasoning.summary","summary":" location","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" parameter","reasoning_details":[{"type":"reasoning.summary","summary":" parameter","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" Even","reasoning_details":[{"type":"reasoning.summary","summary":" Even","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" though","reasoning_details":[{"type":"reasoning.summary","summary":" though","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" there's","reasoning_details":[{"type":"reasoning.summary","summary":" there's","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" a","reasoning_details":[{"type":"reasoning.summary","summary":" a","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" multi","reasoning_details":[{"type":"reasoning.summary","summary":" multi","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":"_tool","reasoning_details":[{"type":"reasoning.summary","summary":"_tool","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":"_use","reasoning_details":[{"type":"reasoning.summary","summary":"_use","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":".parallel","reasoning_details":[{"type":"reasoning.summary","summary":".parallel","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" option","reasoning_details":[{"type":"reasoning.summary","summary":" option","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" for","reasoning_details":[{"type":"reasoning.summary","summary":" for","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" running","reasoning_details":[{"type":"reasoning.summary","summary":" running","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" multiple","reasoning_details":[{"type":"reasoning.summary","summary":" multiple","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" tools","reasoning_details":[{"type":"reasoning.summary","summary":" tools","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" I'm","reasoning_details":[{"type":"reasoning.summary","summary":" I'm","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" focused","reasoning_details":[{"type":"reasoning.summary","summary":" focused","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" on","reasoning_details":[{"type":"reasoning.summary","summary":" on","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" just","reasoning_details":[{"type":"reasoning.summary","summary":" just","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" one","reasoning_details":[{"type":"reasoning.summary","summary":" one","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" tool","reasoning_details":[{"type":"reasoning.summary","summary":" tool","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" here","reasoning_details":[{"type":"reasoning.summary","summary":" here","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" so","reasoning_details":[{"type":"reasoning.summary","summary":" so","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" I'll","reasoning_details":[{"type":"reasoning.summary","summary":" I'll","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" go","reasoning_details":[{"type":"reasoning.summary","summary":" go","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" ahead","reasoning_details":[{"type":"reasoning.summary","summary":" ahead","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" and","reasoning_details":[{"type":"reasoning.summary","summary":" and","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" call","reasoning_details":[{"type":"reasoning.summary","summary":" call","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" functions","reasoning_details":[{"type":"reasoning.summary","summary":" functions","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":".weather","reasoning_details":[{"type":"reasoning.summary","summary":".weather","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" directly","reasoning_details":[{"type":"reasoning.summary","summary":" directly","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" with","reasoning_details":[{"type":"reasoning.summary","summary":" with","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" \"","reasoning_details":[{"type":"reasoning.summary","summary":" \"","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":"Flor","reasoning_details":[{"type":"reasoning.summary","summary":"Flor","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":"ence","reasoning_details":[{"type":"reasoning.summary","summary":"ence","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" Italy","reasoning_details":[{"type":"reasoning.summary","summary":" Italy","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":".\"","reasoning_details":[{"type":"reasoning.summary","summary":".\"","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" I'll","reasoning_details":[{"type":"reasoning.summary","summary":" I'll","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" make","reasoning_details":[{"type":"reasoning.summary","summary":" make","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" sure","reasoning_details":[{"type":"reasoning.summary","summary":" sure","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" to","reasoning_details":[{"type":"reasoning.summary","summary":" to","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" use","reasoning_details":[{"type":"reasoning.summary","summary":" use","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" commentary","reasoning_details":[{"type":"reasoning.summary","summary":" commentary","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" channel","reasoning_details":[{"type":"reasoning.summary","summary":" channel","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" for","reasoning_details":[{"type":"reasoning.summary","summary":" for","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" this","reasoning_details":[{"type":"reasoning.summary","summary":" this","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" call","reasoning_details":[{"type":"reasoning.summary","summary":" call","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" Once","reasoning_details":[{"type":"reasoning.summary","summary":" Once","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" I","reasoning_details":[{"type":"reasoning.summary","summary":" I","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" receive","reasoning_details":[{"type":"reasoning.summary","summary":" receive","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" weather","reasoning_details":[{"type":"reasoning.summary","summary":" weather","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" response","reasoning_details":[{"type":"reasoning.summary","summary":" response","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":",","reasoning_details":[{"type":"reasoning.summary","summary":",","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" I'll","reasoning_details":[{"type":"reasoning.summary","summary":" I'll","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" present","reasoning_details":[{"type":"reasoning.summary","summary":" present","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" the","reasoning_details":[{"type":"reasoning.summary","summary":" the","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" information","reasoning_details":[{"type":"reasoning.summary","summary":" information","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" clearly","reasoning_details":[{"type":"reasoning.summary","summary":" clearly","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" and","reasoning_details":[{"type":"reasoning.summary","summary":" and","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" succinct","reasoning_details":[{"type":"reasoning.summary","summary":" succinct","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":"ly","reasoning_details":[{"type":"reasoning.summary","summary":"ly","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":".","reasoning_details":[{"type":"reasoning.summary","summary":".","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" Let's","reasoning_details":[{"type":"reasoning.summary","summary":" Let's","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":" go","reasoning_details":[{"type":"reasoning.summary","summary":" go","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning":"!","reasoning_details":[{"type":"reasoning.summary","summary":"!","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"reasoning_details":[{"type":"reasoning.encrypted","data":"gAAAAABpgJDXAuR0HjlWRtFfesnymrYPPQR9I9gY-4gyB4kiZ_mdXFEOJLsYevTBaNB1wjNviCSnJU0F9Icw2vm542wsByAW0SCh-u5tckaejCd1Eo5gMrgWWSwGKT3xmHzZHMjqxkUGG7orIHGQlIZPr7pHwxTGLp8jmQK_mH7oiDADSjmclCD73KGLOoLlYQLMTq1HGZHAKjCtv-l7uNB1Vst33Hnd2rwayvRXRCQBtgZwotY7AE4vF2Em3pOZSiWu-1u0FkkDhOQd9QupaKRTcPX5PZpFG_FfD6Elwsp-MMH4wtpk96WDc7y0dLouWW5H_pxblrvXQqbpeFVyk1wJ9Xzy7NjcJYnVwt04rdtUjqXBwFJN0HOtYH8TvW2u3mz8x-nj29UxwRMtzPDwXLoAiSRYo6KAZRU4cryLCqiOlTMB3Yedr0RuWkIWU4_oO38whChA8vawvTlcHgPPEYeKAlmEYyOR4mlDAR-r6zGw6fFCSjQ_J9HdlOpeLXm-Y-a5WFzl_FXYE0CVqUzBMMR2PSs6VO4DR73ATdl62SIVW-4kLgPYVurYyv8VUM3H1Z_bb2kInDpqXwK2IUwX08BNRnMvi_wPvm7pTEeKQCxj9-D8rLTIsK8C2tfaDZReKhCymy0KBF9UWDFKlHcM58zU1N7o2YHfVO6b61SWYLra4H7eewBv2levoiSoeVFjar787rf8bqeoPn-mkwASjgKWyDvUwcsLA2vMm8eMclk4qryY8LbgCvX320Zo5byUXblt9f2wTDZhQblmXLaW-9vTBjrbPqtDc2LW_ZkLoSApnrlQxvu0AnaqVUDGHVFERlbZcuU35JJ-","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","format":"openai-responses-v1","index":0}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_0bKx1gHreGnPuO8CzsleyyRQ","type":"function","function":{"name":"weather","arguments":""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"location"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Flor"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"ence"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":","}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" Italy"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"}"}}]},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5gf37iohnb"}
+
+ data: {"id":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","object":"chat.completion.chunk","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"provider_metadata":{"openai":{"responseId":"resp_0430adf43712f48201698090d6c4048196b485fe56c0face13","serviceTier":"default"},"gateway":{"routing":{"originalModelId":"openai/gpt-5","resolvedProvider":"openai","resolvedProviderApiModelId":"gpt-5-2025-08-07","internalResolvedModelId":"openai:gpt-5-2025-08-07","fallbacksAvailable":["azure"],"internalReasoning":"Selected openai as preferred provider for gpt-5. 1 fallback(s) available: azure","planningReasoning":"System credentials planned for: openai, azure. Total execution order: openai(system) ā azure(system)","canonicalSlug":"openai/gpt-5","finalProvider":"openai","attempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":1725623.377813,"endTime":1725855.622852,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"openai/gpt-5","canonicalSlug":"openai/gpt-5","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":1725623.377813,"endTime":1725855.622852,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.00219875","marketCost":"0.00219875","generationId":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":63,"completion_tokens":148,"total_tokens":211,"cost":0.00219875,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":64,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.00219875},"system_fingerprint":"fp_5gf37iohnb","generationId":"gen_01KGF3BHK17PHK9V9DEN2A1ZAE"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 339.492ms
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2375
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"call_0bKx1gHreGnPuO8CzsleyyRQ","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"openai-responses-v1","index":0,"summary":"**Getting weather information**\n\nI need to retrieve the weather using the designated tool, specifically the functions.weather with the location parameter. Even though there''s a multi_tool_use.parallel option for running multiple tools, I''m focused on just one tool here, so I''ll go ahead and call functions.weather directly with \"Florence, Italy.\" I''ll make sure to use the commentary channel for this call. Once I receive the weather response, I''ll present the information clearly and succinctly. Let''s go!","type":"reasoning.summary"},{"data":"gAAAAABpgJDXAuR0HjlWRtFfesnymrYPPQR9I9gY-4gyB4kiZ_mdXFEOJLsYevTBaNB1wjNviCSnJU0F9Icw2vm542wsByAW0SCh-u5tckaejCd1Eo5gMrgWWSwGKT3xmHzZHMjqxkUGG7orIHGQlIZPr7pHwxTGLp8jmQK_mH7oiDADSjmclCD73KGLOoLlYQLMTq1HGZHAKjCtv-l7uNB1Vst33Hnd2rwayvRXRCQBtgZwotY7AE4vF2Em3pOZSiWu-1u0FkkDhOQd9QupaKRTcPX5PZpFG_FfD6Elwsp-MMH4wtpk96WDc7y0dLouWW5H_pxblrvXQqbpeFVyk1wJ9Xzy7NjcJYnVwt04rdtUjqXBwFJN0HOtYH8TvW2u3mz8x-nj29UxwRMtzPDwXLoAiSRYo6KAZRU4cryLCqiOlTMB3Yedr0RuWkIWU4_oO38whChA8vawvTlcHgPPEYeKAlmEYyOR4mlDAR-r6zGw6fFCSjQ_J9HdlOpeLXm-Y-a5WFzl_FXYE0CVqUzBMMR2PSs6VO4DR73ATdl62SIVW-4kLgPYVurYyv8VUM3H1Z_bb2kInDpqXwK2IUwX08BNRnMvi_wPvm7pTEeKQCxj9-D8rLTIsK8C2tfaDZReKhCymy0KBF9UWDFKlHcM58zU1N7o2YHfVO6b61SWYLra4H7eewBv2levoiSoeVFjar787rf8bqeoPn-mkwASjgKWyDvUwcsLA2vMm8eMclk4qryY8LbgCvX320Zo5byUXblt9f2wTDZhQblmXLaW-9vTBjrbPqtDc2LW_ZkLoSApnrlQxvu0AnaqVUDGHVFERlbZcuU35JJ-","format":"openai-responses-v1","id":"rs_0430adf43712f48201698090d71990819682f523d5f4a4cd6a","index":0,"type":"reasoning.encrypted"}]},{"content":"40 C","tool_call_id":"call_0bKx1gHreGnPuO8CzsleyyRQ","role":"tool"}],"model":"openai/gpt-5","stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"enabled":true},"stream":true}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ body: |+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"role":"assistant"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"It"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"ās"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" currently"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" around"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"40"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"°C"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" Florence"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" Italy"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" If"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"ād"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" like"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" I"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" also"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" provide"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" brief"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" forecast"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" tips"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" staying"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" cool"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":" heat"},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"system_fingerprint":"fp_5vwx38gjaf"}
+
+ data: {"id":"gen_01KGF3BP39K37NP6M0N1QWVXE1","object":"chat.completion.chunk","created":1770033371,"model":"openai/gpt-5","choices":[{"index":0,"delta":{"provider_metadata":{"openai":{"responseId":"resp_0430adf43712f48201698090db6338819696794d34dd844e52","serviceTier":"default"},"gateway":{"routing":{"originalModelId":"openai/gpt-5","resolvedProvider":"openai","resolvedProviderApiModelId":"gpt-5-2025-08-07","internalResolvedModelId":"openai:gpt-5-2025-08-07","fallbacksAvailable":["azure"],"internalReasoning":"Selected openai as preferred provider for gpt-5. 1 fallback(s) available: azure","planningReasoning":"System credentials planned for: openai, azure. Total execution order: openai(system) ā azure(system)","canonicalSlug":"openai/gpt-5","finalProvider":"openai","attempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":1477248.277749,"endTime":1477458.808981,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"openai/gpt-5","canonicalSlug":"openai/gpt-5","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":1477248.277749,"endTime":1477458.808981,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.00049125","marketCost":"0.00049125","generationId":"gen_01KGF3BP39K37NP6M0N1QWVXE1","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":97,"completion_tokens":37,"total_tokens":134,"cost":0.00049125,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.00049125},"system_fingerprint":"fp_5vwx38gjaf","generationId":"gen_01KGF3BP39K37NP6M0N1QWVXE1"}
+
+ data: [DONE]
+
+ headers:
+ Content-Type:
+ - text/event-stream
+ status: 200 OK
+ code: 200
+ duration: 304.872667ms
diff --git a/internal/fantasy/providertests/testdata/TestVercelThinking/gpt-5/thinking.yaml b/internal/fantasy/providertests/testdata/TestVercelThinking/gpt-5/thinking.yaml
new file mode 100644
index 000000000..0b1b34f72
--- /dev/null
+++ b/internal/fantasy/providertests/testdata/TestVercelThinking/gpt-5/thinking.yaml
@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 466
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"}],"model":"openai/gpt-5","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"enabled":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF3B3C7Q42KHM2W985XF2T3","object":"chat.completion","created":1770033356,"model":"openai/gpt-5","choices":[{"index":0,"message":{"role":"assistant","content":null,"reasoning":"**Checking weather in Florence**\n\nI need to answer the user regarding the weather in Florence, Italy. I have access to a functions.weather tool for this purpose. Since we''re only calling one tool, I donāt need to use the multi_tool_use feature, which is meant for parallel calls. Iāll simply use functions.weather directly. Iāll provide the location as \"Florence, Italy\" and then wait for the results. Fingers crossed the tool gives us the correct data!","reasoning_details":[{"type":"reasoning.summary","summary":"**Checking weather in Florence**\n\nI need to answer the user regarding the weather in Florence, Italy. I have access to a functions.weather tool for this purpose. Since we''re only calling one tool, I donāt need to use the multi_tool_use feature, which is meant for parallel calls. Iāll simply use functions.weather directly. Iāll provide the location as \"Florence, Italy\" and then wait for the results. Fingers crossed the tool gives us the correct data!","id":"rs_0562170428b0ad7001698090c89354819687c27b2705c3ce4c","format":"openai-responses-v1","index":0},{"type":"reasoning.encrypted","data":"gAAAAABpgJDMsf0VPNBZL3A8tONVzmCdRytZjL7k3QaiavhXgEfFZ0_E6LPvHdpQha_hZs16TnpTURpI-a0UEqxQ0ogIISECklCdduz3wdG0_h55n2hL-NL07dwRdFhygz4tmLJo9mqbUsn1D0uWEu-4afSiPP1HUVoyM3P-XAqG0iDZBG0S3MTxzLCkS9kRgQlzROJlaXEmEB9AJdyFXmb7zAABESJ5kGlH6sT0Iakwvl8vVr34M-OwgYCCGQ6ppz-m0UQmNhCBlcq08d8KkpYElyOQ8hbbykatWslxGZzBWLz7leWClihD4iMM72zbWnwXZDshOqp4lObx1TZuLlDI_naQj6yNXVMRolOSq7g_SygrgJ4o8vmDWUu8Tt_pAHcjWTbzhhTOo-X0-OubpEPgOdjvjdGnQ3tuS5BZs39XVsN0CL2L_XzL6zdVKGdCkqEwoiXjJSLtSFZLgQvn5bzmIPY0II0xX4CAeSN8oHhE4CnocBqWrU3PRaKPHM0WypqB0UuM254n_cZBvdKC9OaJfWKmVbdI1H5R0arzb3KYBG8DXpuWVO354MtLSZ6ZaqxJDNapHX9nwGZ2muBBzYSqxsdYFuLSxz3J-uAwA8YM8o6yb8otfhXrmiHS_562EofNf1yKoFX2j4lACJFTFRWpDRl-ytnfW_VCXvdEelBlmB40JuFu6qy_lF0_g-CndYzGXOi714BIPR0dvcNOLpX_w71QA4WHJUvm7udhzvcHvIkNZHu3O8lUl7htEJGYnx-6x1vn_XLJBD47TUi4QbbuvmqPcHVfbQ5Z-9Hn-Dc9JMGXhao72RRnilCBeiJcJmjTYTWn4JjgE0yMr9BdJjQv9j5E2p3oPHIB2Dqw1FiIHpw1VaGan4T8N3yRPD6-AinoZggBNkULFTS0lWBPPI0vk4uMWIruJS5l7z8rs08PsBS5kTk6-J4IEp-3--Yy5YJND8Z_zboGaKewpWFeft0FqRklGdJ00e_FGaPD2aOfcOygzlCtKumLhU2XG_E8VvGxjz4-TLlzM3LR35Hgm03amQVV_20JMdI1XB_OSoPKoGCZubzBQsf7E_8zVj23J3wVkFEv6o1Fh4XJ4unWcLeQjjLvT7Bkv-smny6wWN-Fd6SM9yU8fMlTHbRCCVdcGRN6QjcX1K5eOiI8U4qmvQw8Tn9_MtMejUdEkWdiKxACIhOhAqJRlTl8JwQL9ggL1gc4iVMepQuaSvauSVjNWalgq94e-k1tSSkobHt6yGD3Fd9jUwyC6KrWraEWR7tmbWesc1KR_zbsd9J_B57szRFLz0JU6GmTCwRM9sblytuCLLdIeW8FLlqIRyhkYm5HrgKyoYwBLp9yOkfllj6C35ZW5ZTOpLNhmeDi3BOLMh6IvMgak4TCaNJjvmPD7ZVU6Y_--LOe_SCJta3yppo2f4-eOduTsUXcXC-gmpbvAhUBgIyOV55OTSE8OGYHZ86sTdF7UVnzftznjQ-5mZKPiHMTNgastAmdKdNhcjDunKlL-qbyEsX4Eeb9TKXM2koCcxZ-Dfs84wSS","id":"rs_0562170428b0ad7001698090c89354819687c27b2705c3ce4c","format":"openai-responses-v1","index":0}],"tool_calls":[{"id":"call_iHMVWYLENDMIMaQBppQsnQ2Y","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence, Italy\"}"}}],"provider_metadata":{"openai":{"responseId":"resp_0562170428b0ad7001698090c836608196820886f8d884db01","serviceTier":"default"},"gateway":{"routing":{"originalModelId":"openai/gpt-5","resolvedProvider":"openai","resolvedProviderApiModelId":"gpt-5-2025-08-07","internalResolvedModelId":"openai:gpt-5-2025-08-07","fallbacksAvailable":["azure"],"internalReasoning":"Selected openai as preferred provider for gpt-5. 1 fallback(s) available: azure","planningReasoning":"System credentials planned for: openai, azure. Total execution order: openai(system) ā azure(system)","canonicalSlug":"openai/gpt-5","finalProvider":"openai","attempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":1469621.176344,"endTime":1473996.358343,"statusCode":200,"providerResponseId":"resp_0562170428b0ad7001698090c836608196820886f8d884db01"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"openai/gpt-5","canonicalSlug":"openai/gpt-5","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.00215875","marketCost":"0.00215875","generationId":"gen_01KGF3B3C7Q42KHM2W985XF2T3","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":63,"completion_tokens":144,"total_tokens":207,"cost":0.00215875,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":64,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.00215875},"system_fingerprint":"fp_5jkdir3bke","generationId":"gen_01KGF3B3C7Q42KHM2W985XF2T3"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 4.531842958s
+- id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 2977
+ host: ""
+ body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence, Italy?","role":"user"},{"tool_calls":[{"id":"call_iHMVWYLENDMIMaQBppQsnQ2Y","function":{"arguments":"{\"location\":\"Florence, Italy\"}","name":"weather"},"type":"function"}],"role":"assistant","reasoning_details":[{"format":"openai-responses-v1","index":0,"summary":"**Checking weather in Florence**\n\nI need to answer the user regarding the weather in Florence, Italy. I have access to a functions.weather tool for this purpose. Since we''re only calling one tool, I donāt need to use the multi_tool_use feature, which is meant for parallel calls. Iāll simply use functions.weather directly. Iāll provide the location as \"Florence, Italy\" and then wait for the results. Fingers crossed the tool gives us the correct data!","type":"reasoning.summary"},{"data":"gAAAAABpgJDMsf0VPNBZL3A8tONVzmCdRytZjL7k3QaiavhXgEfFZ0_E6LPvHdpQha_hZs16TnpTURpI-a0UEqxQ0ogIISECklCdduz3wdG0_h55n2hL-NL07dwRdFhygz4tmLJo9mqbUsn1D0uWEu-4afSiPP1HUVoyM3P-XAqG0iDZBG0S3MTxzLCkS9kRgQlzROJlaXEmEB9AJdyFXmb7zAABESJ5kGlH6sT0Iakwvl8vVr34M-OwgYCCGQ6ppz-m0UQmNhCBlcq08d8KkpYElyOQ8hbbykatWslxGZzBWLz7leWClihD4iMM72zbWnwXZDshOqp4lObx1TZuLlDI_naQj6yNXVMRolOSq7g_SygrgJ4o8vmDWUu8Tt_pAHcjWTbzhhTOo-X0-OubpEPgOdjvjdGnQ3tuS5BZs39XVsN0CL2L_XzL6zdVKGdCkqEwoiXjJSLtSFZLgQvn5bzmIPY0II0xX4CAeSN8oHhE4CnocBqWrU3PRaKPHM0WypqB0UuM254n_cZBvdKC9OaJfWKmVbdI1H5R0arzb3KYBG8DXpuWVO354MtLSZ6ZaqxJDNapHX9nwGZ2muBBzYSqxsdYFuLSxz3J-uAwA8YM8o6yb8otfhXrmiHS_562EofNf1yKoFX2j4lACJFTFRWpDRl-ytnfW_VCXvdEelBlmB40JuFu6qy_lF0_g-CndYzGXOi714BIPR0dvcNOLpX_w71QA4WHJUvm7udhzvcHvIkNZHu3O8lUl7htEJGYnx-6x1vn_XLJBD47TUi4QbbuvmqPcHVfbQ5Z-9Hn-Dc9JMGXhao72RRnilCBeiJcJmjTYTWn4JjgE0yMr9BdJjQv9j5E2p3oPHIB2Dqw1FiIHpw1VaGan4T8N3yRPD6-AinoZggBNkULFTS0lWBPPI0vk4uMWIruJS5l7z8rs08PsBS5kTk6-J4IEp-3--Yy5YJND8Z_zboGaKewpWFeft0FqRklGdJ00e_FGaPD2aOfcOygzlCtKumLhU2XG_E8VvGxjz4-TLlzM3LR35Hgm03amQVV_20JMdI1XB_OSoPKoGCZubzBQsf7E_8zVj23J3wVkFEv6o1Fh4XJ4unWcLeQjjLvT7Bkv-smny6wWN-Fd6SM9yU8fMlTHbRCCVdcGRN6QjcX1K5eOiI8U4qmvQw8Tn9_MtMejUdEkWdiKxACIhOhAqJRlTl8JwQL9ggL1gc4iVMepQuaSvauSVjNWalgq94e-k1tSSkobHt6yGD3Fd9jUwyC6KrWraEWR7tmbWesc1KR_zbsd9J_B57szRFLz0JU6GmTCwRM9sblytuCLLdIeW8FLlqIRyhkYm5HrgKyoYwBLp9yOkfllj6C35ZW5ZTOpLNhmeDi3BOLMh6IvMgak4TCaNJjvmPD7ZVU6Y_--LOe_SCJta3yppo2f4-eOduTsUXcXC-gmpbvAhUBgIyOV55OTSE8OGYHZ86sTdF7UVnzftznjQ-5mZKPiHMTNgastAmdKdNhcjDunKlL-qbyEsX4Eeb9TKXM2koCcxZ-Dfs84wSS","format":"openai-responses-v1","id":"rs_0562170428b0ad7001698090c89354819687c27b2705c3ce4c","index":0,"type":"reasoning.encrypted"}]},{"content":"40 C","tool_call_id":"call_iHMVWYLENDMIMaQBppQsnQ2Y","role":"tool"}],"model":"openai/gpt-5","tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"reasoning":{"enabled":true}}'
+ headers:
+ Accept:
+ - application/json
+ Content-Type:
+ - application/json
+ User-Agent:
+ - OpenAI/Go 2.7.1
+ url: https://ai-gateway.vercel.sh/v1/chat/completions
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ content_length: -1
+ uncompressed: true
+ body: '{"id":"gen_01KGF3B7PMN3C6EZGFX1P9A78S","object":"chat.completion","created":1770033366,"model":"openai/gpt-5","choices":[{"index":0,"message":{"role":"assistant","content":"Right now in Florence, Italy itās about 40°C (104°F). Want a forecast or more details?","reasoning":"**Presenting the temperature**\n\nThe tool returned \"40 C,\" which feels a bit too brief. I think I should present this clearly to the user. Converting 40 C to Fahrenheit gives us 104 F. I want to keep it concise, so Iāll say, \"Right now in Florence, itās about 40°C (104°F).\" I should also offer to get a forecast or details like humidity, while sticking with the details that are most relevant and avoiding assumptions about the weather.**Considering the heat advisory**\n\nI realize that 40 C is extremely hot! I could include a simple advisory like \"stay hydrated,\" but it might come off as unsolicited. Since the instructions emphasize being concise, I think Iāll keep the final message straightforward: \"Right now in Florence, Italy, it''s around 40°C (104°F). Would you like a forecast or more details?\" That way, Iām providing the info without overstepping.","reasoning_details":[{"type":"reasoning.summary","summary":"**Presenting the temperature**\n\nThe tool returned \"40 C,\" which feels a bit too brief. I think I should present this clearly to the user. Converting 40 C to Fahrenheit gives us 104 F. I want to keep it concise, so Iāll say, \"Right now in Florence, itās about 40°C (104°F).\" I should also offer to get a forecast or details like humidity, while sticking with the details that are most relevant and avoiding assumptions about the weather.**Considering the heat advisory**\n\nI realize that 40 C is extremely hot! I could include a simple advisory like \"stay hydrated,\" but it might come off as unsolicited. Since the instructions emphasize being concise, I think Iāll keep the final message straightforward: \"Right now in Florence, Italy, it''s around 40°C (104°F). Would you like a forecast or more details?\" That way, Iām providing the info without overstepping.","id":"rs_0562170428b0ad7001698090cd65008196b1811384c1eb1d6c","format":"openai-responses-v1","index":0},{"type":"reasoning.encrypted","data":"gAAAAABpgJDWD7uuI9cHJYRhaE0aumxBFm7lcXL0q4zfSOYK50X0LE6YwVz7CUc7g6HDCOxpi78m5CX5xe4sR7mloQRkr8YuAFOv_draZ0tZ21FJhKoEr7x8XyzCgrx-Mxv98HGsZE7V3cF61q8b4VZVb4r5MAPDCaZyUINTj2tLAdZChdxpwq4ZBDGhUVrYdqoPbFZm-rx9gkWOKSP7ir9aWU3L5qkQcay0i7zYj0p2Gp8iL1A--48RYacfVaXOgpfYGCBvo0whLwTVtjXxCy0_OEmkSp4bMjkd9dq3PibuD_XwN5mU3QxPW-qiF1zwsS26WQ1Zw0xwvg188l5-MMSaWhJZkZdkWFGmsmazBglfMOncPQO3khM2158ca0W6aeo0WryrEQWNeb37sJjrT258fQ_0NA9Udn0YWUXWdOndCXM7el37_JqxB-4fng9iseMEM9jx5wJ4gtinOVovootaQPYe8Vg68juw0FWgcywsJsbK1GKZNaT7-ISsgcy6Cq8uijY6S9jDn2mUxry1PZz702OrpQSkuYn_YLwXM3bPBsMIn_5sTTm4Z4FZUEXVHndT5U5-klkfzBtAYXpA1cnT65_FVqZydKo_KSLYwbssjUZL8K2QCq1MWJ8X2Lq84i0lmbX-i8Nh205TEi31ub_syPKa-pQ-r-6W0glXUCUTIuqpvGMthEOGb6YVeBhVkzenPtPSeVXWeF0oHZuuQpFbfaF2m1lxGIkETgowuRvDU7S2UOb-B1kTfDpzfFsgxXHtbBhE03tw49_EU5h8h-fCBxiR8Tc6ZylJsAUsEszEH0ofcsuF33IrhTpbLlCXN3wsfSucUq9O4NtgLO-B5VuqPOdFTJ4mbR70C_Cve-Wt4VmGekrsmD1wTImf0o9X3d_ZvZ190dkG7XDAJRDdCMK5uflIBY-fYb7TEKqtnV9WrGR1wY38lpJDzboxOXit99XOHGL64z5oCiD9K0_4BPTRbaHL9Gn8ohO4lQo0NIN4wGRD2YYHaPPjFDK4Fgr_sq8JVp4GsdZ82VyhWjE9XmX2L6VMZff44je18xTHbCRNU0BnTlkpqYea_LFip7pdZcbITnMgDrZi9zrqEpx5AjVoqBr3v7tsLP206LYwQ2g1KjNzhTStPgw3FEyKgcfrLDD9FQ7xjmvHRGWAQ_29MdVTG93M8ypEE77GkMf4AdDwa0uXOhw-k7wJe3QR206ZFzZT4fn1sDy55O0_1F-fmoPm9Ow1Cuw7W0p2oZgBShQU_IhVR3NtRF269WM28bCoCyohF71tgSzMm_dyW2qtkPhptO6Xpw2r2xUpH7AqPIC073m8O3PvfPnmr_MKQ6tS6mUH5sOqu8wrqhwuLsM3j3Pcze-2sCb8gRsw7UfrE0ed_ZTbJmbWRZbKSbX7nvGs_TVB4SpKTCe8VNtmk_4CKc0TP0ZHimi_O8CkOUn7WE7edN--E-6xuZxA47IsE1DkLXtJPuAbJZrk2XshkePp-icDeWPQ0csiLAriBRFlZQBiquXNWBsALiZK0RdchPSq5uLOPVEisXlzPgDAalfxNY2eti3vxTMIAGjZnu4QBYIrd4bUg2AAA9d5OX-TsSO0m3j1lS2sHtekYdr34ofA5dT0ntWdsaQ2WS-8WHYDmGN7TZBcfTJC784EPpoKXuTIwr9NiUAB71FRyk_wY6TdhoDqDw4KtCw28l1QMXGFK3wv0koIHOGVCjuB5IQK7NWNnyned5kSqVgkGY-epfBtvEdcdc7CCBcA7yf-qoGd7idCBnjqcMszsKMD2d95sDDO3nqNV51vhjfA9fxuo-HlGNv12PbsePQTZXSzRM9kVX7jWiu-MFgUfPtZrzYMVh97QA586AZH40Zp5D2NZpfpFFCHFxWCHbhtRhklzeBu1gQ-iWmpxzns2XypqiL5STk4JeBYoav4B7-ypRBO8mwQUEzheZgKO5Hi0jWElzqcWvO2sAouwciUP7-8Tjl0NDLAs7MzuvwtCkzH8o9ikw1vR8MmLToCgUZ1BFHZn5_EH-VWGiZ0x2kikoLM-iHi0fBFUcdj2XrVQ4mnU6IbHh2ST4Xfltx7CmssTxVvK357mX_5Aq5U-13XAJRjGaYX1rsclnudN8N2ib8LYiukfq_Rqxzxdm0QjLuc-vdGLm5V2vdJ2qX5fwrVMaVJgwt393P42SsVoyzkYPpwn4eXfiQssdjPdLkJpLFcjQ==","id":"rs_0562170428b0ad7001698090cd65008196b1811384c1eb1d6c","format":"openai-responses-v1","index":0}],"provider_metadata":{"openai":{"responseId":"resp_0562170428b0ad7001698090ccce248196b6d739df157f9b65","serviceTier":"default"},"gateway":{"routing":{"originalModelId":"openai/gpt-5","resolvedProvider":"openai","resolvedProviderApiModelId":"gpt-5-2025-08-07","internalResolvedModelId":"openai:gpt-5-2025-08-07","fallbacksAvailable":["azure"],"internalReasoning":"Selected openai as preferred provider for gpt-5. 1 fallback(s) available: azure","planningReasoning":"System credentials planned for: openai, azure. Total execution order: openai(system) ā azure(system)","canonicalSlug":"openai/gpt-5","finalProvider":"openai","attempts":[{"provider":"openai","internalModelId":"openai:gpt-5-2025-08-07","providerApiModelId":"gpt-5-2025-08-07","credentialType":"system","success":true,"startTime":7725848.499705,"endTime":7735703.317098,"statusCode":200,"providerResponseId":"resp_0562170428b0ad7001698090ccce248196b6d739df157f9b65"}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"openai/gpt-5","canonicalSlug":"openai/gpt-5","success":false,"providerAttemptCount":0,"providerAttempts":[]}],"totalProviderAttemptCount":0},"cost":"0.00479","marketCost":"0.00479","generationId":"gen_01KGF3B7PMN3C6EZGFX1P9A78S","billableWebSearchCalls":0}}},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":216,"completion_tokens":260,"total_tokens":476,"cost":0.00479,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0,"upstream_inference_completions_cost":0},"completion_tokens_details":{"reasoning_tokens":192,"image_tokens":0},"cache_creation_input_tokens":0,"market_cost":0.00479},"system_fingerprint":"fp_bemblx56dt","generationId":"gen_01KGF3B7PMN3C6EZGFX1P9A78S"}'
+ headers:
+ Content-Type:
+ - application/json
+ status: 200 OK
+ code: 200
+ duration: 10.00759025s
diff --git a/internal/fantasy/providertests/testdata/wish.png b/internal/fantasy/providertests/testdata/wish.png
new file mode 100644
index 000000000..ff7992d89
Binary files /dev/null and b/internal/fantasy/providertests/testdata/wish.png differ
diff --git a/internal/fantasy/providertests/vercel_test.go b/internal/fantasy/providertests/vercel_test.go
new file mode 100644
index 000000000..0361ec0ba
--- /dev/null
+++ b/internal/fantasy/providertests/vercel_test.go
@@ -0,0 +1,124 @@
+package providertests
+
+import (
+ "net/http"
+ "os"
+ "testing"
+
+ "charm.land/fantasy"
+ "charm.land/fantasy/providers/anthropic"
+ "charm.land/fantasy/providers/vercel"
+ "charm.land/x/vcr"
+ "github.com/stretchr/testify/require"
+)
+
+var vercelTestModels = []testModel{
+ {"claude-sonnet-4", "anthropic/claude-sonnet-4", true},
+ {"gemini-2.5-flash", "google/gemini-2.5-flash", false},
+ {"gpt-5", "openai/gpt-5", true},
+ {"gemini-3-pro-preview", "google/gemini-3-pro-preview", true},
+}
+
+func TestVercelCommon(t *testing.T) {
+ var pairs []builderPair
+ for _, m := range vercelTestModels {
+ pairs = append(pairs, builderPair{m.name, vercelBuilder(m.model), nil, nil})
+ }
+ testCommon(t, pairs)
+}
+
+func TestVercelCommonWithAnthropicCache(t *testing.T) {
+ testCommon(t, []builderPair{
+ {"claude-sonnet-4", vercelBuilder("anthropic/claude-sonnet-4"), nil, addAnthropicCaching},
+ })
+}
+
+func TestVercelThinking(t *testing.T) {
+ enabled := true
+ opts := fantasy.ProviderOptions{
+ vercel.Name: &vercel.ProviderOptions{
+ Reasoning: &vercel.ReasoningOptions{
+ Enabled: &enabled,
+ },
+ },
+ }
+
+ var pairs []builderPair
+ for _, m := range vercelTestModels {
+ if !m.reasoning {
+ continue
+ }
+ pairs = append(pairs, builderPair{m.name, vercelBuilder(m.model), opts, nil})
+ }
+ testThinking(t, pairs, testVercelThinking)
+
+ // test anthropic signature
+ testThinking(t, []builderPair{
+ {"claude-sonnet-4-sig", vercelBuilder("anthropic/claude-sonnet-4"), opts, nil},
+ }, testVercelThinkingWithSignature)
+}
+
+func testVercelThinkingWithSignature(t *testing.T, result *fantasy.AgentResult) {
+ reasoningContentCount := 0
+ signaturesCount := 0
+ // Test if we got the signature
+ for _, step := range result.Steps {
+ for _, msg := range step.Messages {
+ for _, content := range msg.Content {
+ if content.GetType() == fantasy.ContentTypeReasoning {
+ reasoningContentCount += 1
+ reasoningContent, ok := fantasy.AsContentType[fantasy.ReasoningPart](content)
+ if !ok {
+ continue
+ }
+ if len(reasoningContent.ProviderOptions) == 0 {
+ continue
+ }
+
+ anthropicReasoningMetadata, ok := reasoningContent.ProviderOptions[anthropic.Name]
+ if !ok {
+ continue
+ }
+ if reasoningContent.Text != "" {
+ if typed, ok := anthropicReasoningMetadata.(*anthropic.ReasoningOptionMetadata); ok {
+ require.NotEmpty(t, typed.Signature)
+ signaturesCount += 1
+ }
+ }
+ }
+ }
+ }
+ }
+ require.Greater(t, reasoningContentCount, 0)
+ require.Greater(t, signaturesCount, 0)
+ require.Equal(t, reasoningContentCount, signaturesCount)
+ // we also add the anthropic metadata so test that
+ testAnthropicThinking(t, result)
+}
+
+func testVercelThinking(t *testing.T, result *fantasy.AgentResult) {
+ reasoningContentCount := 0
+ for _, step := range result.Steps {
+ for _, msg := range step.Messages {
+ for _, content := range msg.Content {
+ if content.GetType() == fantasy.ContentTypeReasoning {
+ reasoningContentCount += 1
+ }
+ }
+ }
+ }
+ require.Greater(t, reasoningContentCount, 0)
+}
+
+func vercelBuilder(model string) builderFunc {
+ return func(t *testing.T, r *vcr.Recorder) (fantasy.LanguageModel, error) {
+ provider, err := vercel.New(
+ vercel.WithAPIKey(os.Getenv("FANTASY_VERCEL_API_KEY")),
+ vercel.WithHTTPClient(&http.Client{Transport: r}),
+ )
+ if err != nil {
+ return nil, err
+ }
+ return provider.LanguageModel(t.Context(), model)
+ }
+}
diff --git a/internal/fantasy/retry.go b/internal/fantasy/retry.go
new file mode 100644
index 000000000..6b2c2a412
--- /dev/null
+++ b/internal/fantasy/retry.go
@@ -0,0 +1,137 @@
+package fantasy
+
+import (
+ "context"
+ "errors"
+ "strconv"
+ "time"
+)
+
+// RetryFn is a function that returns a value and an error.
+type RetryFn[T any] func() (T, error)
+
+// RetryFunction is a function that retries another function.
+type RetryFunction[T any] func(ctx context.Context, fn RetryFn[T]) (T, error)
+
+// getRetryDelayInMs calculates the retry delay based on error headers and exponential backoff.
+func getRetryDelayInMs(err error, exponentialBackoffDelay time.Duration) time.Duration {
+ var providerErr *ProviderError
+ if !errors.As(err, &providerErr) || providerErr.ResponseHeaders == nil {
+ return exponentialBackoffDelay
+ }
+
+ headers := providerErr.ResponseHeaders
+ var ms time.Duration
+
+ // retry-ms is more precise than retry-after and used by e.g. OpenAI
+ if retryAfterMs, exists := headers["retry-after-ms"]; exists {
+ if timeoutMs, err := strconv.ParseFloat(retryAfterMs, 64); err == nil {
+ ms = time.Duration(timeoutMs) * time.Millisecond
+ }
+ }
+
+ // About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
+ if retryAfter, exists := headers["retry-after"]; exists && ms == 0 {
+ if timeoutSeconds, err := strconv.ParseFloat(retryAfter, 64); err == nil {
+ ms = time.Duration(timeoutSeconds) * time.Second
+ } else {
+ // Try parsing as HTTP date
+ if t, err := time.Parse(time.RFC1123, retryAfter); err == nil {
+ ms = time.Until(t)
+ }
+ }
+ }
+
+ // Check that the delay is reasonable:
+ // 0 <= ms < 60 seconds or ms < exponentialBackoffDelay
+ if ms > 0 && (ms < 60*time.Second || ms < exponentialBackoffDelay) {
+ return ms
+ }
+
+ return exponentialBackoffDelay
+}
+
+// isAbortError checks if the error is a context cancellation error.
+func isAbortError(err error) bool {
+ return errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded)
+}
+
+// RetryWithExponentialBackoffRespectingRetryHeaders creates a retry function that retries
+// a failed operation with exponential backoff, while respecting rate limit headers
+// (retry-after-ms and retry-after) if they are provided and reasonable (0-60 seconds).
+func RetryWithExponentialBackoffRespectingRetryHeaders[T any](options RetryOptions) RetryFunction[T] {
+ return func(ctx context.Context, fn RetryFn[T]) (T, error) {
+ return retryWithExponentialBackoff(ctx, fn, options, nil)
+ }
+}
+
+// RetryOptions configures the retry behavior.
+type RetryOptions struct {
+ MaxRetries int
+ InitialDelayIn time.Duration
+ BackoffFactor float64
+ OnRetry OnRetryCallback
+}
+
+// OnRetryCallback defines a function that is called when a retry occurs.
+type OnRetryCallback = func(err *ProviderError, delay time.Duration)
+
+// DefaultRetryOptions returns the default retry options.
+// DefaultRetryOptions returns the default retry options.
+func DefaultRetryOptions() RetryOptions {
+ return RetryOptions{
+ MaxRetries: 2,
+ InitialDelayIn: 2000 * time.Millisecond,
+ BackoffFactor: 2.0,
+ }
+}
+
+// retryWithExponentialBackoff implements the retry logic with exponential backoff.
+func retryWithExponentialBackoff[T any](ctx context.Context, fn RetryFn[T], options RetryOptions, allErrors []error) (T, error) {
+ var zero T
+ result, err := fn()
+ if err == nil {
+ return result, nil
+ }
+
+ if isAbortError(err) {
+ return zero, err // don't retry when the request was aborted
+ }
+
+ if options.MaxRetries == 0 {
+ return zero, err // don't wrap the error when retries are disabled
+ }
+
+ newErrors := append(allErrors, err)
+ tryNumber := len(newErrors)
+
+ if tryNumber > options.MaxRetries {
+ return zero, &RetryError{newErrors}
+ }
+
+ var providerErr *ProviderError
+ if errors.As(err, &providerErr) && providerErr.IsRetryable() && tryNumber <= options.MaxRetries {
+ delay := getRetryDelayInMs(err, options.InitialDelayIn)
+ if options.OnRetry != nil {
+ options.OnRetry(providerErr, delay)
+ }
+
+ select {
+ case <-time.After(delay):
+ // Continue with retry
+ case <-ctx.Done():
+ return zero, ctx.Err()
+ }
+
+ newOptions := options
+ newOptions.InitialDelayIn = time.Duration(float64(options.InitialDelayIn) * options.BackoffFactor)
+
+ return retryWithExponentialBackoff(ctx, fn, newOptions, newErrors)
+ }
+
+ if tryNumber == 1 {
+ return zero, err // don't wrap the error when a non-retryable error occurs on the first try
+ }
+
+ return zero, &RetryError{newErrors}
+}
diff --git a/internal/fantasy/schema/schema.go b/internal/fantasy/schema/schema.go
new file mode 100644
index 000000000..c1cc46d2b
--- /dev/null
+++ b/internal/fantasy/schema/schema.go
@@ -0,0 +1,442 @@
+// Package schema provides JSON schema generation and validation utilities.
+// It supports automatic schema generation from Go types and validation of parsed objects.
+package schema
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "reflect"
+ "slices"
+ "strings"
+
+ "charm.land/fantasy/jsonrepair"
+ "github.com/kaptinlin/jsonschema"
+)
+
+// ObjectRepairFunc is a function that attempts to repair invalid JSON output.
+// It receives the raw text and the error encountered during parsing or validation,
+// and returns repaired text or an error if repair is not possible.
+type ObjectRepairFunc func(ctx context.Context, text string, err error) (string, error)
+
+// ParseError is returned when object generation fails
+// due to parsing errors, validation errors, or model failures.
+type ParseError struct {
+ RawText string
+ ParseError error
+ ValidationError error
+}
+
+// Schema represents a JSON schema for tool input validation.
+type Schema struct {
+ Type string `json:"type,omitempty"`
+ Properties map[string]*Schema `json:"properties,omitempty"`
+ Required []string `json:"required,omitempty"`
+ Items *Schema `json:"items,omitempty"`
+ Description string `json:"description,omitempty"`
+ Enum []any `json:"enum,omitempty"`
+ Format string `json:"format,omitempty"`
+ Minimum *float64 `json:"minimum,omitempty"`
+ Maximum *float64 `json:"maximum,omitempty"`
+ MinLength *int `json:"minLength,omitempty"`
+ MaxLength *int `json:"maxLength,omitempty"`
+}
+
+// ParseState represents the state of JSON parsing.
+type ParseState string
+
+const (
+ // ParseStateUndefined means input was undefined/empty.
+ ParseStateUndefined ParseState = "undefined"
+
+ // ParseStateSuccessful means JSON parsed without repair.
+ ParseStateSuccessful ParseState = "successful"
+
+ // ParseStateRepaired means JSON parsed after repair.
+ ParseStateRepaired ParseState = "repaired"
+
+ // ParseStateFailed means JSON could not be parsed even after repair.
+ ParseStateFailed ParseState = "failed"
+)
+
+// ToParameters converts a Schema to the parameters map format expected by ToolInfo.
+func ToParameters(s Schema) map[string]any {
+ if s.Properties == nil {
+ return make(map[string]any)
+ }
+
+ result := make(map[string]any)
+ for name, propSchema := range s.Properties {
+ result[name] = ToMap(*propSchema)
+ }
+ return result
+}
+
+// Generate generates a JSON schema from a reflect.Type.
+// It recursively processes struct fields, arrays, maps, and primitive types.
+func Generate(t reflect.Type) Schema {
+ return generateSchemaRecursive(t, make(map[reflect.Type]bool))
+}
+
+func generateSchemaRecursive(t reflect.Type, visited map[reflect.Type]bool) Schema {
+ if t.Kind() == reflect.Pointer {
+ t = t.Elem()
+ }
+
+ if visited[t] {
+ return Schema{Type: "object"}
+ }
+ visited[t] = true
+ defer delete(visited, t)
+
+ switch t.Kind() {
+ case reflect.String:
+ return Schema{Type: "string"}
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+ reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return Schema{Type: "integer"}
+ case reflect.Float32, reflect.Float64:
+ return Schema{Type: "number"}
+ case reflect.Bool:
+ return Schema{Type: "boolean"}
+ case reflect.Slice, reflect.Array:
+ itemSchema := generateSchemaRecursive(t.Elem(), visited)
+ return Schema{
+ Type: "array",
+ Items: &itemSchema,
+ }
+ case reflect.Map:
+ if t.Key().Kind() == reflect.String {
+ valueSchema := generateSchemaRecursive(t.Elem(), visited)
+ schema := Schema{
+ Type: "object",
+ Properties: map[string]*Schema{
+ "*": &valueSchema,
+ },
+ }
+ return schema
+ }
+ return Schema{Type: "object"}
+ case reflect.Struct:
+ schema := Schema{
+ Type: "object",
+ Properties: make(map[string]*Schema),
+ }
+ for i := range t.NumField() {
+ field := t.Field(i)
+
+ if !field.IsExported() {
+ continue
+ }
+
+ jsonTag := field.Tag.Get("json")
+ if jsonTag == "-" {
+ continue
+ }
+
+ fieldName := field.Name
+ required := true
+
+ if jsonTag != "" {
+ parts := strings.Split(jsonTag, ",")
+ if parts[0] != "" {
+ fieldName = parts[0]
+ }
+
+ if slices.Contains(parts[1:], "omitempty") {
+ required = false
+ }
+ } else {
+ fieldName = toSnakeCase(fieldName)
+ }
+
+ fieldSchema := generateSchemaRecursive(field.Type, visited)
+
+ if desc := field.Tag.Get("description"); desc != "" {
+ fieldSchema.Description = desc
+ }
+
+ if enumTag := field.Tag.Get("enum"); enumTag != "" {
+ enumValues := strings.Split(enumTag, ",")
+ fieldSchema.Enum = make([]any, len(enumValues))
+ for i, v := range enumValues {
+ fieldSchema.Enum[i] = strings.TrimSpace(v)
+ }
+ }
+
+ schema.Properties[fieldName] = &fieldSchema
+
+ if required {
+ schema.Required = append(schema.Required, fieldName)
+ }
+ }
+
+ return schema
+ case reflect.Interface:
+ return Schema{Type: "object"}
+ default:
+ return Schema{Type: "object"}
+ }
+}
+
+// ToMap converts a Schema to a map representation suitable for JSON Schema.
+func ToMap(schema Schema) map[string]any {
+ result := make(map[string]any)
+
+ if schema.Type != "" {
+ result["type"] = schema.Type
+ }
+
+ if schema.Description != "" {
+ result["description"] = schema.Description
+ }
+
+ if len(schema.Enum) > 0 {
+ result["enum"] = schema.Enum
+ }
+
+ if schema.Format != "" {
+ result["format"] = schema.Format
+ }
+
+ if schema.Minimum != nil {
+ result["minimum"] = *schema.Minimum
+ }
+
+ if schema.Maximum != nil {
+ result["maximum"] = *schema.Maximum
+ }
+
+ if schema.MinLength != nil {
+ result["minLength"] = *schema.MinLength
+ }
+
+ if schema.MaxLength != nil {
+ result["maxLength"] = *schema.MaxLength
+ }
+
+ if schema.Properties != nil {
+ props := make(map[string]any)
+ for name, propSchema := range schema.Properties {
+ props[name] = ToMap(*propSchema)
+ }
+ result["properties"] = props
+ }
+
+ if len(schema.Required) > 0 {
+ result["required"] = schema.Required
+ }
+
+ if schema.Items != nil {
+ itemsMap := ToMap(*schema.Items)
+ // Ensure type is always set for items, even if it was blank for llama.cpp compatibility
+ if _, hasType := itemsMap["type"]; !hasType && schema.Items.Type == "" {
+ if len(schema.Items.Properties) > 0 {
+ itemsMap["type"] = "object"
+ }
+ }
+ result["items"] = itemsMap
+ }
+
+ return result
+}
+
+// ParsePartialJSON attempts to parse potentially incomplete JSON.
+// It first tries standard JSON parsing, then attempts repair if that fails.
+//
+// Returns:
+// - result: The parsed JSON value (map, slice, or primitive)
+// - state: Indicates whether parsing succeeded, needed repair, or failed
+// - err: The error if parsing failed completely
+//
+// Example:
+//
+// obj, state, err := ParsePartialJSON(`{"name": "John", "age": 25`)
+// // Result: map[string]any{"name": "John", "age": 25}, ParseStateRepaired, nil
+func ParsePartialJSON(text string) (any, ParseState, error) {
+ if text == "" {
+ return nil, ParseStateUndefined, nil
+ }
+
+ var result any
+ if err := json.Unmarshal([]byte(text), &result); err == nil {
+ return result, ParseStateSuccessful, nil
+ }
+
+ repaired, err := jsonrepair.RepairJSON(text)
+ if err != nil {
+ return nil, ParseStateFailed, fmt.Errorf("json repair failed: %w", err)
+ }
+
+ if err := json.Unmarshal([]byte(repaired), &result); err != nil {
+ return nil, ParseStateFailed, fmt.Errorf("failed to parse repaired json: %w", err)
+ }
+
+ return result, ParseStateRepaired, nil
+}
+
+// Error implements the error interface.
+func (e *ParseError) Error() string {
+ if e.ValidationError != nil {
+ return fmt.Sprintf("object validation failed: %v", e.ValidationError)
+ }
+ if e.ParseError != nil {
+ return fmt.Sprintf("failed to parse object: %v", e.ParseError)
+ }
+ return "failed to generate object"
+}
+
+// ParseAndValidate combines JSON parsing and validation.
+// Returns the parsed object if both parsing and validation succeed.
+func ParseAndValidate(text string, schema Schema) (any, error) {
+ obj, state, err := ParsePartialJSON(text)
+ if state == ParseStateFailed {
+ return nil, &ParseError{
+ RawText: text,
+ ParseError: err,
+ }
+ }
+
+ if err := validateAgainstSchema(obj, schema); err != nil {
+ return nil, &ParseError{
+ RawText: text,
+ ValidationError: err,
+ }
+ }
+
+ return obj, nil
+}
+
+// ValidateAgainstSchema validates a parsed object against a Schema.
+func ValidateAgainstSchema(obj any, schema Schema) error {
+ return validateAgainstSchema(obj, schema)
+}
+
+func validateAgainstSchema(obj any, schema Schema) error {
+ jsonSchemaBytes, err := json.Marshal(schema)
+ if err != nil {
+ return fmt.Errorf("failed to marshal schema: %w", err)
+ }
+
+ compiler := jsonschema.NewCompiler()
+ validator, err := compiler.Compile(jsonSchemaBytes)
+ if err != nil {
+ return fmt.Errorf("invalid schema: %w", err)
+ }
+
+ result := validator.Validate(obj)
+ if !result.IsValid() {
+ var errMsgs []string
+ for field, validationErr := range result.Errors {
+ errMsgs = append(errMsgs, fmt.Sprintf("%s: %s", field, validationErr.Message))
+ }
+ return fmt.Errorf("validation failed: %s", strings.Join(errMsgs, "; "))
+ }
+
+ return nil
+}
+
+// ParseAndValidateWithRepair attempts parsing, validation, and custom repair.
+func ParseAndValidateWithRepair(
+ ctx context.Context,
+ text string,
+ schema Schema,
+ repair ObjectRepairFunc,
+) (any, error) {
+ obj, state, parseErr := ParsePartialJSON(text)
+
+ if state == ParseStateSuccessful || state == ParseStateRepaired {
+ validationErr := validateAgainstSchema(obj, schema)
+ if validationErr == nil {
+ return obj, nil
+ }
+
+ if repair != nil {
+ repairedText, repairErr := repair(ctx, text, validationErr)
+ if repairErr == nil {
+ obj2, state2, _ := ParsePartialJSON(repairedText)
+ if state2 == ParseStateSuccessful || state2 == ParseStateRepaired {
+ if err := validateAgainstSchema(obj2, schema); err == nil {
+ return obj2, nil
+ }
+ }
+ }
+ }
+
+ return nil, &ParseError{
+ RawText: text,
+ ValidationError: validationErr,
+ }
+ }
+
+ if repair != nil {
+ repairedText, repairErr := repair(ctx, text, parseErr)
+ if repairErr == nil {
+ obj2, state2, parseErr2 := ParsePartialJSON(repairedText)
+ if state2 == ParseStateSuccessful || state2 == ParseStateRepaired {
+ if err := validateAgainstSchema(obj2, schema); err == nil {
+ return obj2, nil
+ }
+ }
+ return nil, &ParseError{
+ RawText: repairedText,
+ ParseError: parseErr2,
+ }
+ }
+ }
+
+ return nil, &ParseError{
+ RawText: text,
+ ParseError: parseErr,
+ }
+}
+
+func toSnakeCase(s string) string {
+ var result strings.Builder
+ for i, r := range s {
+ if i > 0 && r >= 'A' && r <= 'Z' {
+ result.WriteByte('_')
+ }
+ result.WriteRune(r)
+ }
+ return strings.ToLower(result.String())
+}
+
+// Normalize recursively normalizes a raw JSON Schema map so it is
+// compatible with providers that reject type-arrays (e.g. OpenAI). Type
+// arrays are converted to anyOf and bare "array" types get "items":{}.
+func Normalize(node map[string]any) {
+ for _, child := range node {
+ switch v := child.(type) {
+ case map[string]any:
+ Normalize(v)
+ case []any:
+ for _, item := range v {
+ if m, ok := item.(map[string]any); ok {
+ Normalize(m)
+ }
+ }
+ }
+ }
+
+ typeArr, ok := node["type"].([]any)
+ if !ok {
+ if node["type"] == "array" {
+ if _, has := node["items"]; !has {
+ node["items"] = map[string]any{}
+ }
+ }
+ return
+ }
+
+ anyOf := make([]any, 0, len(typeArr))
+ for _, t := range typeArr {
+ variant := map[string]any{"type": t}
+ if t == "array" {
+ variant["items"] = map[string]any{}
+ }
+ anyOf = append(anyOf, variant)
+ }
+ delete(node, "type")
+ node["anyOf"] = anyOf
+}
diff --git a/internal/fantasy/schema/schema_test.go b/internal/fantasy/schema/schema_test.go
new file mode 100644
index 000000000..8b48194ec
--- /dev/null
+++ b/internal/fantasy/schema/schema_test.go
@@ -0,0 +1,639 @@
+package schema
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestEnumSupport(t *testing.T) {
+ // Test enum via struct tags
+ type WeatherInput struct {
+ Location string `json:"location" description:"City name"`
+ Units string `json:"units" enum:"celsius,fahrenheit,kelvin" description:"Temperature units"`
+ Format string `json:"format,omitempty" enum:"json,xml,text"`
+ }
+
+ schema := Generate(reflect.TypeFor[WeatherInput]())
+
+ require.Equal(t, "object", schema.Type)
+
+ // Check units field has enum values
+ unitsSchema := schema.Properties["units"]
+ require.NotNil(t, unitsSchema, "Expected units property to exist")
+ require.Len(t, unitsSchema.Enum, 3)
+ expectedUnits := []string{"celsius", "fahrenheit", "kelvin"}
+ for i, expected := range expectedUnits {
+ require.Equal(t, expected, unitsSchema.Enum[i])
+ }
+
+ // Check required fields (format should not be required due to omitempty)
+ expectedRequired := []string{"location", "units"}
+ require.Len(t, schema.Required, len(expectedRequired))
+}
+
+func TestSchemaToParameters(t *testing.T) {
+ testSchema := Schema{
+ Type: "object",
+ Properties: map[string]*Schema{
+ "name": {
+ Type: "string",
+ Description: "The name field",
+ },
+ "age": {
+ Type: "integer",
+ Minimum: func() *float64 { v := 0.0; return &v }(),
+ Maximum: func() *float64 { v := 120.0; return &v }(),
+ },
+ "tags": {
+ Type: "array",
+ Items: &Schema{
+ Type: "string",
+ },
+ },
+ "priority": {
+ Type: "string",
+ Enum: []any{"low", "medium", "high"},
+ },
+ },
+ Required: []string{"name"},
+ }
+
+ params := ToParameters(testSchema)
+
+ // Check name parameter
+ nameParam, ok := params["name"].(map[string]any)
+ require.True(t, ok, "Expected name parameter to exist")
+ require.Equal(t, "string", nameParam["type"])
+ require.Equal(t, "The name field", nameParam["description"])
+
+ // Check age parameter with min/max
+ ageParam, ok := params["age"].(map[string]any)
+ require.True(t, ok, "Expected age parameter to exist")
+ require.Equal(t, "integer", ageParam["type"])
+ require.Equal(t, 0.0, ageParam["minimum"])
+ require.Equal(t, 120.0, ageParam["maximum"])
+
+ // Check priority parameter with enum
+ priorityParam, ok := params["priority"].(map[string]any)
+ require.True(t, ok, "Expected priority parameter to exist")
+ require.Equal(t, "string", priorityParam["type"])
+ enumValues, ok := priorityParam["enum"].([]any)
+ require.True(t, ok)
+ require.Len(t, enumValues, 3)
+}
+
+func TestGenerateSchemaBasicTypes(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ input any
+ expected Schema
+ }{
+ {
+ name: "string type",
+ input: "",
+ expected: Schema{Type: "string"},
+ },
+ {
+ name: "int type",
+ input: 0,
+ expected: Schema{Type: "integer"},
+ },
+ {
+ name: "int64 type",
+ input: int64(0),
+ expected: Schema{Type: "integer"},
+ },
+ {
+ name: "uint type",
+ input: uint(0),
+ expected: Schema{Type: "integer"},
+ },
+ {
+ name: "float64 type",
+ input: 0.0,
+ expected: Schema{Type: "number"},
+ },
+ {
+ name: "float32 type",
+ input: float32(0.0),
+ expected: Schema{Type: "number"},
+ },
+ {
+ name: "bool type",
+ input: false,
+ expected: Schema{Type: "boolean"},
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
+ schema := Generate(reflect.TypeOf(tt.input))
+ require.Equal(t, tt.expected.Type, schema.Type)
+ })
+ }
+}
+
+func TestGenerateSchemaArrayTypes(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ input any
+ expected Schema
+ }{
+ {
+ name: "string slice",
+ input: []string{},
+ expected: Schema{
+ Type: "array",
+ Items: &Schema{Type: "string"},
+ },
+ },
+ {
+ name: "int slice",
+ input: []int{},
+ expected: Schema{
+ Type: "array",
+ Items: &Schema{Type: "integer"},
+ },
+ },
+ {
+ name: "string array",
+ input: [3]string{},
+ expected: Schema{
+ Type: "array",
+ Items: &Schema{Type: "string"},
+ },
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
+ schema := Generate(reflect.TypeOf(tt.input))
+ require.Equal(t, tt.expected.Type, schema.Type)
+ require.NotNil(t, schema.Items, "Expected items schema to exist")
+ require.Equal(t, tt.expected.Items.Type, schema.Items.Type)
+ })
+ }
+}
+
+func TestGenerateSchemaMapTypes(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ input any
+ expected string
+ }{
+ {
+ name: "string to string map",
+ input: map[string]string{},
+ expected: "object",
+ },
+ {
+ name: "string to int map",
+ input: map[string]int{},
+ expected: "object",
+ },
+ {
+ name: "int to string map",
+ input: map[int]string{},
+ expected: "object",
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
+ schema := Generate(reflect.TypeOf(tt.input))
+ require.Equal(t, tt.expected, schema.Type)
+ })
+ }
+}
+
+func TestGenerateSchemaStructTypes(t *testing.T) {
+ t.Parallel()
+
+ type SimpleStruct struct {
+ Name string `json:"name" description:"The name field"`
+ Age int `json:"age"`
+ }
+
+ type StructWithOmitEmpty struct {
+ Required string `json:"required"`
+ Optional string `json:"optional,omitempty"`
+ }
+
+ type StructWithJSONIgnore struct {
+ Visible string `json:"visible"`
+ Hidden string `json:"-"`
+ }
+
+ type StructWithoutJSONTags struct {
+ FirstName string
+ LastName string
+ }
+
+ tests := []struct {
+ name string
+ input any
+ validate func(t *testing.T, schema Schema)
+ }{
+ {
+ name: "simple struct",
+ input: SimpleStruct{},
+ validate: func(t *testing.T, schema Schema) {
+ require.Equal(t, "object", schema.Type)
+ require.Len(t, schema.Properties, 2)
+ require.NotNil(t, schema.Properties["name"], "Expected name property to exist")
+ require.Equal(t, "The name field", schema.Properties["name"].Description)
+ require.Len(t, schema.Required, 2)
+ },
+ },
+ {
+ name: "struct with omitempty",
+ input: StructWithOmitEmpty{},
+ validate: func(t *testing.T, schema Schema) {
+ require.Len(t, schema.Required, 1)
+ require.Equal(t, "required", schema.Required[0])
+ },
+ },
+ {
+ name: "struct with json ignore",
+ input: StructWithJSONIgnore{},
+ validate: func(t *testing.T, schema Schema) {
+ require.Len(t, schema.Properties, 1)
+ require.NotNil(t, schema.Properties["visible"], "Expected visible property to exist")
+ require.Nil(t, schema.Properties["hidden"], "Expected hidden property to not exist")
+ },
+ },
+ {
+ name: "struct without json tags",
+ input: StructWithoutJSONTags{},
+ validate: func(t *testing.T, schema Schema) {
+ require.NotNil(t, schema.Properties["first_name"], "Expected first_name property to exist")
+ require.NotNil(t, schema.Properties["last_name"], "Expected last_name property to exist")
+ },
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
+ schema := Generate(reflect.TypeOf(tt.input))
+ tt.validate(t, schema)
+ })
+ }
+}
+
+func TestGenerateSchemaPointerTypes(t *testing.T) {
+ t.Parallel()
+
+ type StructWithPointers struct {
+ Name *string `json:"name"`
+ Age *int `json:"age"`
+ }
+
+ schema := Generate(reflect.TypeFor[StructWithPointers]())
+
+ require.Equal(t, "object", schema.Type)
+
+ require.NotNil(t, schema.Properties["name"], "Expected name property to exist")
+ require.Equal(t, "string", schema.Properties["name"].Type)
+
+ require.NotNil(t, schema.Properties["age"], "Expected age property to exist")
+ require.Equal(t, "integer", schema.Properties["age"].Type)
+}
+
+func TestGenerateSchemaNestedStructs(t *testing.T) {
+ t.Parallel()
+
+ type Address struct {
+ Street string `json:"street"`
+ City string `json:"city"`
+ }
+
+ type Person struct {
+ Name string `json:"name"`
+ Address Address `json:"address"`
+ }
+
+ schema := Generate(reflect.TypeFor[Person]())
+
+ require.Equal(t, "object", schema.Type)
+
+ require.NotNil(t, schema.Properties["address"], "Expected address property to exist")
+
+ addressSchema := schema.Properties["address"]
+ require.Equal(t, "object", addressSchema.Type)
+
+ require.NotNil(t, addressSchema.Properties["street"], "Expected street property in address to exist")
+ require.NotNil(t, addressSchema.Properties["city"], "Expected city property in address to exist")
+}
+
+func TestGenerateSchemaRecursiveStructs(t *testing.T) {
+ t.Parallel()
+
+ type Node struct {
+ Value string `json:"value"`
+ Next *Node `json:"next,omitempty"`
+ }
+
+ schema := Generate(reflect.TypeFor[Node]())
+
+ require.Equal(t, "object", schema.Type)
+
+ require.NotNil(t, schema.Properties["value"], "Expected value property to exist")
+
+ require.NotNil(t, schema.Properties["next"], "Expected next property to exist")
+
+ // The recursive reference should be handled gracefully
+ nextSchema := schema.Properties["next"]
+ require.Equal(t, "object", nextSchema.Type)
+}
+
+func TestGenerateSchemaWithEnumTags(t *testing.T) {
+ t.Parallel()
+
+ type ConfigInput struct {
+ Level string `json:"level" enum:"debug,info,warn,error" description:"Log level"`
+ Format string `json:"format" enum:"json,text"`
+ Optional string `json:"optional,omitempty" enum:"a,b,c"`
+ }
+
+ schema := Generate(reflect.TypeFor[ConfigInput]())
+
+ // Check level field
+ levelSchema := schema.Properties["level"]
+ require.NotNil(t, levelSchema, "Expected level property to exist")
+ require.Len(t, levelSchema.Enum, 4)
+ expectedLevels := []string{"debug", "info", "warn", "error"}
+ for i, expected := range expectedLevels {
+ require.Equal(t, expected, levelSchema.Enum[i])
+ }
+
+ // Check format field
+ formatSchema := schema.Properties["format"]
+ require.NotNil(t, formatSchema, "Expected format property to exist")
+ require.Len(t, formatSchema.Enum, 2)
+
+ // Check required fields (optional should not be required due to omitempty)
+ expectedRequired := []string{"level", "format"}
+ require.Len(t, schema.Required, len(expectedRequired))
+}
+
+func TestGenerateSchemaComplexTypes(t *testing.T) {
+ t.Parallel()
+
+ type ComplexInput struct {
+ StringSlice []string `json:"string_slice"`
+ IntMap map[string]int `json:"int_map"`
+ NestedSlice []map[string]string `json:"nested_slice"`
+ Interface any `json:"interface"`
+ }
+
+ schema := Generate(reflect.TypeFor[ComplexInput]())
+
+ // Check string slice
+ stringSliceSchema := schema.Properties["string_slice"]
+ require.NotNil(t, stringSliceSchema, "Expected string_slice property to exist")
+ require.Equal(t, "array", stringSliceSchema.Type)
+ require.Equal(t, "string", stringSliceSchema.Items.Type)
+
+ // Check int map
+ intMapSchema := schema.Properties["int_map"]
+ require.NotNil(t, intMapSchema, "Expected int_map property to exist")
+ require.Equal(t, "object", intMapSchema.Type)
+
+ // Check nested slice
+ nestedSliceSchema := schema.Properties["nested_slice"]
+ require.NotNil(t, nestedSliceSchema, "Expected nested_slice property to exist")
+ require.Equal(t, "array", nestedSliceSchema.Type)
+ require.Equal(t, "object", nestedSliceSchema.Items.Type)
+
+ // Check interface
+ interfaceSchema := schema.Properties["interface"]
+ require.NotNil(t, interfaceSchema, "Expected interface property to exist")
+ require.Equal(t, "object", interfaceSchema.Type)
+}
+
+func TestToSnakeCase(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ input string
+ expected string
+ }{
+ {"FirstName", "first_name"},
+ {"XMLHttpRequest", "x_m_l_http_request"},
+ {"ID", "i_d"},
+ {"HTTPSProxy", "h_t_t_p_s_proxy"},
+ {"simple", "simple"},
+ {"", ""},
+ {"A", "a"},
+ {"AB", "a_b"},
+ {"CamelCase", "camel_case"},
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.input, func(t *testing.T) {
+ t.Parallel()
+ result := toSnakeCase(tt.input)
+ require.Equal(t, tt.expected, result, "toSnakeCase(%s)", tt.input)
+ })
+ }
+}
+
+func TestSchemaToParametersEdgeCases(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ schema Schema
+ expected map[string]any
+ }{
+ {
+ name: "non-object schema",
+ schema: Schema{
+ Type: "string",
+ },
+ expected: map[string]any{},
+ },
+ {
+ name: "object with no properties",
+ schema: Schema{
+ Type: "object",
+ Properties: nil,
+ },
+ expected: map[string]any{},
+ },
+ {
+ name: "object with empty properties",
+ schema: Schema{
+ Type: "object",
+ Properties: map[string]*Schema{},
+ },
+ expected: map[string]any{},
+ },
+ {
+ name: "schema with all constraint types",
+ schema: Schema{
+ Type: "object",
+ Properties: map[string]*Schema{
+ "text": {
+ Type: "string",
+ Format: "email",
+ MinLength: func() *int { v := 5; return &v }(),
+ MaxLength: func() *int { v := 100; return &v }(),
+ },
+ "number": {
+ Type: "number",
+ Minimum: func() *float64 { v := 0.0; return &v }(),
+ Maximum: func() *float64 { v := 100.0; return &v }(),
+ },
+ },
+ },
+ expected: map[string]any{
+ "text": map[string]any{
+ "type": "string",
+ "format": "email",
+ "minLength": 5,
+ "maxLength": 100,
+ },
+ "number": map[string]any{
+ "type": "number",
+ "minimum": 0.0,
+ "maximum": 100.0,
+ },
+ },
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
+ result := ToParameters(tt.schema)
+ require.Len(t, result, len(tt.expected))
+ for key, expectedValue := range tt.expected {
+ require.NotNil(t, result[key], "Expected parameter %s to exist", key)
+ // Deep comparison would be complex, so we'll check key properties
+ resultParam := result[key].(map[string]any)
+ expectedParam := expectedValue.(map[string]any)
+ for propKey, propValue := range expectedParam {
+ require.Equal(t, propValue, resultParam[propKey], "Expected %s.%s", key, propKey)
+ }
+ }
+ })
+ }
+}
+
+func TestNormalize_TypeArray(t *testing.T) {
+ t.Parallel()
+
+ node := map[string]any{
+ "type": "object",
+ "properties": map[string]any{
+ "value": map[string]any{
+ "description": "Config value",
+ "type": []any{"string", "number", "boolean", "object", "array", "null"},
+ },
+ },
+ }
+
+ Normalize(node)
+
+ val := node["properties"].(map[string]any)["value"].(map[string]any)
+ require.Nil(t, val["type"])
+ anyOf, ok := val["anyOf"].([]any)
+ require.True(t, ok)
+ require.Len(t, anyOf, 6)
+
+ for _, v := range anyOf {
+ variant := v.(map[string]any)
+ if variant["type"] == "array" {
+ require.Contains(t, variant, "items")
+ }
+ }
+ require.Equal(t, "Config value", val["description"])
+}
+
+func TestNormalize_SingleStringType(t *testing.T) {
+ t.Parallel()
+
+ node := map[string]any{
+ "type": "object",
+ "properties": map[string]any{
+ "name": map[string]any{"type": "string"},
+ },
+ }
+
+ Normalize(node)
+
+ val := node["properties"].(map[string]any)["name"].(map[string]any)
+ require.Equal(t, "string", val["type"])
+}
+
+func TestNormalize_BareArrayGetsItems(t *testing.T) {
+ t.Parallel()
+
+ node := map[string]any{
+ "type": "object",
+ "properties": map[string]any{
+ "tags": map[string]any{"type": "array"},
+ },
+ }
+
+ Normalize(node)
+
+ val := node["properties"].(map[string]any)["tags"].(map[string]any)
+ require.Equal(t, "array", val["type"])
+ require.Contains(t, val, "items")
+}
+
+func TestNormalize_SingleElementTypeArray(t *testing.T) {
+ t.Parallel()
+
+ node := map[string]any{
+ "type": "object",
+ "properties": map[string]any{
+ "name": map[string]any{"type": []any{"string"}},
+ },
+ }
+
+ Normalize(node)
+
+ val := node["properties"].(map[string]any)["name"].(map[string]any)
+ require.Nil(t, val["type"])
+ anyOf, ok := val["anyOf"].([]any)
+ require.True(t, ok)
+ require.Len(t, anyOf, 1)
+ require.Equal(t, "string", anyOf[0].(map[string]any)["type"])
+}
+
+func TestNormalize_NestedProperties(t *testing.T) {
+ t.Parallel()
+
+ node := map[string]any{
+ "type": "object",
+ "properties": map[string]any{
+ "config": map[string]any{
+ "type": "object",
+ "properties": map[string]any{
+ "val": map[string]any{"type": []any{"string", "number"}},
+ },
+ },
+ },
+ }
+
+ Normalize(node)
+
+ val := node["properties"].(map[string]any)["config"].(map[string]any)["properties"].(map[string]any)["val"].(map[string]any)
+ require.Nil(t, val["type"])
+ require.NotNil(t, val["anyOf"])
+}
diff --git a/internal/fantasy/scripts/run-labeler.sh b/internal/fantasy/scripts/run-labeler.sh
new file mode 100644
index 000000000..4ac4bc2a5
--- /dev/null
+++ b/internal/fantasy/scripts/run-labeler.sh
@@ -0,0 +1,12 @@
+ISSUES=$(gh issue list --state=all --limit=1000 --json "number" -t '{{range .}}{{printf "%.0f\n" .number}}{{end}}')
+PRS=$(gh pr list --state=all --limit=1000 --json "number" -t '{{range .}}{{printf "%.0f\n" .number}}{{end}}')
+
+for issue in $ISSUES; do
+ echo "Dispatching labeler.yml for $issue"
+ gh workflow run labeler.yml -f issue-number="$issue"
+done
+
+for pr in $PRS; do
+ echo "Dispatching labeler.yml for $pr"
+ gh workflow run labeler.yml -f issue-number="$pr"
+done
diff --git a/internal/fantasy/tool.go b/internal/fantasy/tool.go
new file mode 100644
index 000000000..be146ef3f
--- /dev/null
+++ b/internal/fantasy/tool.go
@@ -0,0 +1,175 @@
+package fantasy
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "reflect"
+
+ "charm.land/fantasy/schema"
+)
+
+// Schema represents a JSON schema for tool input validation.
+type Schema = schema.Schema
+
+// ToolInfo represents tool metadata, matching the existing pattern.
+type ToolInfo struct {
+ Name string `json:"name"`
+ Description string `json:"description"`
+ Parameters map[string]any `json:"parameters"`
+ Required []string `json:"required"`
+ Parallel bool `json:"parallel"` // Whether this tool can run in parallel with other tools
+}
+
+// ToolCall represents a tool invocation, matching the existing pattern.
+type ToolCall struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+ Input string `json:"input"`
+}
+
+// ToolResponse represents the response from a tool execution, matching the existing pattern.
+type ToolResponse struct {
+ Type string `json:"type"`
+ Content string `json:"content"`
+ // Data contains binary data for image/media responses (e.g., image bytes, audio data).
+ Data []byte `json:"data,omitempty"`
+ // MediaType specifies the MIME type of the media (e.g., "image/png", "audio/wav").
+ MediaType string `json:"media_type,omitempty"`
+ Metadata string `json:"metadata,omitempty"`
+ IsError bool `json:"is_error"`
+}
+
+// NewTextResponse creates a text response.
+func NewTextResponse(content string) ToolResponse {
+ return ToolResponse{
+ Type: "text",
+ Content: content,
+ }
+}
+
+// NewTextErrorResponse creates an error response.
+func NewTextErrorResponse(content string) ToolResponse {
+ return ToolResponse{
+ Type: "text",
+ Content: content,
+ IsError: true,
+ }
+}
+
+// NewImageResponse creates an image response with binary data.
+func NewImageResponse(data []byte, mediaType string) ToolResponse {
+ return ToolResponse{
+ Type: "image",
+ Data: data,
+ MediaType: mediaType,
+ }
+}
+
+// NewMediaResponse creates a media response with binary data (e.g., audio, video).
+func NewMediaResponse(data []byte, mediaType string) ToolResponse {
+ return ToolResponse{
+ Type: "media",
+ Data: data,
+ MediaType: mediaType,
+ }
+}
+
+// WithResponseMetadata adds metadata to a response.
+func WithResponseMetadata(response ToolResponse, metadata any) ToolResponse {
+ if metadata != nil {
+ metadataBytes, err := json.Marshal(metadata)
+ if err != nil {
+ return response
+ }
+ response.Metadata = string(metadataBytes)
+ }
+ return response
+}
+
+// AgentTool represents a tool that can be called by a language model.
+// This matches the existing BaseTool interface pattern.
+type AgentTool interface {
+ Info() ToolInfo
+ Run(ctx context.Context, params ToolCall) (ToolResponse, error)
+ ProviderOptions() ProviderOptions
+ SetProviderOptions(opts ProviderOptions)
+}
+
+// NewAgentTool creates a typed tool from a function with automatic schema generation.
+// This is the recommended way to create tools.
+func NewAgentTool[TInput any](
+ name string,
+ description string,
+ fn func(ctx context.Context, input TInput, call ToolCall) (ToolResponse, error),
+) AgentTool {
+ var input TInput
+ schema := schema.Generate(reflect.TypeOf(input))
+
+ return &funcToolWrapper[TInput]{
+ name: name,
+ description: description,
+ fn: fn,
+ schema: schema,
+ parallel: false, // Default to sequential execution
+ }
+}
+
+// NewParallelAgentTool creates a typed tool from a function with automatic schema generation.
+// This also marks a tool as safe to run in parallel with other tools.
+func NewParallelAgentTool[TInput any](
+ name string,
+ description string,
+ fn func(ctx context.Context, input TInput, call ToolCall) (ToolResponse, error),
+) AgentTool {
+ tool := NewAgentTool(name, description, fn)
+ // Try to use the SetParallel method if available
+ if setter, ok := tool.(interface{ SetParallel(bool) }); ok {
+ setter.SetParallel(true)
+ }
+ return tool
+}
+
+// funcToolWrapper wraps a function to implement the AgentTool interface.
+type funcToolWrapper[TInput any] struct {
+ name string
+ description string
+ fn func(ctx context.Context, input TInput, call ToolCall) (ToolResponse, error)
+ schema Schema
+ providerOptions ProviderOptions
+ parallel bool
+}
+
+func (w *funcToolWrapper[TInput]) SetProviderOptions(opts ProviderOptions) {
+ w.providerOptions = opts
+}
+
+func (w *funcToolWrapper[TInput]) ProviderOptions() ProviderOptions {
+ return w.providerOptions
+}
+
+func (w *funcToolWrapper[TInput]) SetParallel(parallel bool) {
+ w.parallel = parallel
+}
+
+func (w *funcToolWrapper[TInput]) Info() ToolInfo {
+ if w.schema.Required == nil {
+ w.schema.Required = []string{}
+ }
+ return ToolInfo{
+ Name: w.name,
+ Description: w.description,
+ Parameters: schema.ToParameters(w.schema),
+ Required: w.schema.Required,
+ Parallel: w.parallel,
+ }
+}
+
+func (w *funcToolWrapper[TInput]) Run(ctx context.Context, params ToolCall) (ToolResponse, error) {
+ var input TInput
+ if err := json.Unmarshal([]byte(params.Input), &input); err != nil {
+ return NewTextErrorResponse(fmt.Sprintf("invalid parameters: %s", err)), nil
+ }
+
+ return w.fn(ctx, input, params)
+}
diff --git a/internal/fantasy/tool_test.go b/internal/fantasy/tool_test.go
new file mode 100644
index 000000000..7567c7cd4
--- /dev/null
+++ b/internal/fantasy/tool_test.go
@@ -0,0 +1,111 @@
+package fantasy
+
+import (
+ "context"
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+// Example of a simple typed tool using the function approach
+type CalculatorInput struct {
+ Expression string `json:"expression" description:"Mathematical expression to evaluate"`
+}
+
+func TestTypedToolFuncExample(t *testing.T) {
+ // Create a typed tool using the function API
+ tool := NewAgentTool(
+ "calculator",
+ "Evaluates simple mathematical expressions",
+ func(ctx context.Context, input CalculatorInput, _ ToolCall) (ToolResponse, error) {
+ if input.Expression == "2+2" {
+ return NewTextResponse("4"), nil
+ }
+ return NewTextErrorResponse("unsupported expression"), nil
+ },
+ )
+
+ // Check the tool info
+ info := tool.Info()
+ require.Equal(t, "calculator", info.Name)
+ require.Len(t, info.Required, 1)
+ require.Equal(t, "expression", info.Required[0])
+
+ // Test execution
+ call := ToolCall{
+ ID: "test-1",
+ Name: "calculator",
+ Input: `{"expression": "2+2"}`,
+ }
+
+ result, err := tool.Run(context.Background(), call)
+ require.NoError(t, err)
+ require.Equal(t, "4", result.Content)
+ require.False(t, result.IsError)
+}
+
+func TestEnumToolExample(t *testing.T) {
+ type WeatherInput struct {
+ Location string `json:"location" description:"City name"`
+ Units string `json:"units" enum:"celsius,fahrenheit" description:"Temperature units"`
+ }
+
+ // Create a weather tool with enum support
+ tool := NewAgentTool(
+ "weather",
+ "Gets current weather for a location",
+ func(ctx context.Context, input WeatherInput, _ ToolCall) (ToolResponse, error) {
+ temp := "22°C"
+ if input.Units == "fahrenheit" {
+ temp = "72°F"
+ }
+ return NewTextResponse(fmt.Sprintf("Weather in %s: %s, sunny", input.Location, temp)), nil
+ },
+ )
+ // Check that the schema includes enum values
+ info := tool.Info()
+ unitsParam, ok := info.Parameters["units"].(map[string]any)
+ require.True(t, ok, "Expected units parameter to exist")
+ enumValues, ok := unitsParam["enum"].([]any)
+ require.True(t, ok)
+ require.Len(t, enumValues, 2)
+
+ // Test execution with enum value
+ call := ToolCall{
+ ID: "test-2",
+ Name: "weather",
+ Input: `{"location": "San Francisco", "units": "fahrenheit"}`,
+ }
+
+ result, err := tool.Run(context.Background(), call)
+ require.NoError(t, err)
+ require.Contains(t, result.Content, "San Francisco")
+ require.Contains(t, result.Content, "72°F")
+}
+
+func TestNewImageResponse(t *testing.T) {
+ imageData := []byte{0x89, 0x50, 0x4E, 0x47} // PNG header bytes
+ mediaType := "image/png"
+
+ resp := NewImageResponse(imageData, mediaType)
+
+ require.Equal(t, "image", resp.Type)
+ require.Equal(t, imageData, resp.Data)
+ require.Equal(t, mediaType, resp.MediaType)
+ require.False(t, resp.IsError)
+ require.Empty(t, resp.Content)
+}
+
+func TestNewMediaResponse(t *testing.T) {
+ audioData := []byte{0x52, 0x49, 0x46, 0x46} // RIFF header bytes
+ mediaType := "audio/wav"
+
+ resp := NewMediaResponse(audioData, mediaType)
+
+ require.Equal(t, "media", resp.Type)
+ require.Equal(t, audioData, resp.Data)
+ require.Equal(t, mediaType, resp.MediaType)
+ require.False(t, resp.IsError)
+ require.Empty(t, resp.Content)
+}
diff --git a/internal/fantasy/util.go b/internal/fantasy/util.go
new file mode 100644
index 000000000..7bb9f48ff
--- /dev/null
+++ b/internal/fantasy/util.go
@@ -0,0 +1,20 @@
+package fantasy
+
+import "github.com/go-viper/mapstructure/v2"
+
+// Opt creates a pointer to the given value.
+func Opt[T any](v T) *T {
+ return &v
+}
+
+// ParseOptions parses the given options map into the provided struct.
+func ParseOptions[T any](options map[string]any, m *T) error {
+ decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
+ TagName: "json",
+ Result: m,
+ })
+ if err != nil {
+ return err
+ }
+ return decoder.Decode(options)
+}